Связанный список MATLAB
Каковы возможные способы реализации связанного списка в MATLAB?
Примечание. Я задаю этот вопрос для педагогической ценности, а не практической ценности. Я понимаю, что если вы на самом деле сворачиваете свой собственный связанный список в MATLAB, вы, вероятно, делаете что-то неправильно. Тем не менее, я TA для класса, интенсивно использующего MATLAB в этом семестре, и моя цель в задании этого вопроса - понять общая структура языка лучше. Поскольку средства программирования общего назначения MATLAB немного необычны, я чувствую, что такой вопрос поможет мне понять их.
Ответы
Ответ 1
MATLAB имеет доступ к Java:
>> a=java.util.LinkedList;
>> li=a.listIterator;
>> li.add(2);
>> li.add(int8(77));
>> li.add(77);
>> li.add(boolean(true));
>> li.add('Mr. Bill');
>> li.previous();
>> li.add([1 2 3 4 5]);
>> a
a =
[2.0, 77, 77.0, true, [[email protected], Mr. Bill]
>> a.get(4)
ans =
1
2
3
4
5
Единственным недостатком этого подхода является то, что MATLAB не имеет возможности маршалировать или сериализовать произвольные объекты MATLAB в Java, вы ограничены с плавающей запятой числа, целые числа (необходимо отбросить их в MATLAB с помощью int8
и т.д.), boolean, строки, массивы и объекты Java.
Ответ 2
Ссылка Lulu, предложенная в комментариях, вероятно, является выбором Я бы сделал, если бы захотел реализовать связанный список в MATLAB. Тем не менее, этот подход отвлекся на объектно-ориентированные функции MATLAB, которые могут быть не такими, какие вы хотите, поскольку вы говорите, что хотите "лучше понять общую структуру языка". Таким образом, вы можете сделать лучше с более простым примером, который включает общие основные функции программирования MATLAB.
В других ответах упоминался ряд общих функций, таких как матрицы и индексирование матриц, создание структур и использование вложенных функций и обработчики функций. Я рассмотрю пример, который использует все эти функции и, надеюсь, дает хорошее введение в ряд ключевых понятий в MATLAB...
Пример кода:
Сохраните код ниже в файле с именем linked_list.m
на пути MATLAB:
function listObject = linked_list(values)
data = reshape(values,1,[]);
listObject = struct('display',@display_list,...
'addAfter',@add_element,...
'delete',@delete_element);
function display_list
%# Displays the data in the list
disp(data);
end
function add_element(values,index)
%# Adds a set of data values after an index in the list, or at the end
%# of the list if the index is larger than the number of list elements
index = min(index,numel(data));
data = [data(1:index) reshape(values,1,[]) data(index+1:end)];
end
function delete_element(index)
%# Deletes an element at an index in the list
data(index) = [];
end
end
Описание:
Функция linked_list
принимает матрицу произвольного размера и сначала преобразует ее в вектор строки с помощью функции RESHAPE. Это становится исходным "связанным списком", хранящимся в переменной data
.
Далее создается структура (с помощью функции STRUCT), которая имеет три элемента: display
, addAfter
, и delete
. Каждое из этих полей хранит дескриптор функции для одной из трех функций, вложенных в родительскую функцию linked_list
. Эти вложенные функции могут обращаться к переменной data
, хранящейся в родительской функции.
Структура listObject
возвращается из linked_list
. Пока эта структура существует в рабочей области, и, таким образом, до тех пор, пока обрабатываемая функция содержит, существует переменная data
, которая будет сохраняться даже после возвращения функции linked_list
. Затем мы можем вызвать вложенные функции (используя их ручки) для изменения переменной data
. Вот пример...
Сначала создайте связанный список "объект" и покажите содержимое:
>> listObj = linked_list([1 2 3]); %# A linked list with three elements
>> listObj.display() %# Access the `display` field and invoke the function
1 2 3
Затем добавьте элемент "4" после второго элемента списка и покажите:
>> listObj.addAfter(4,2) %# Access the `addAfter` field and invoke the function
>> listObj.display()
1 2 4 3
И, наконец, удалите второй элемент списка и покажите:
>> listObj.delete(2) %# Access the `delete` field and invoke the function
>> listObj.display()
1 4 3
Обратите внимание, как вложенные функции add_element
и delete_element
используют индексацию матрицы для изменения переменной data
.
Вы можете расширить этот пример, чтобы создать множество других вложенных функций для работы в связанном списке, добавив новые поля в структуру для хранения своих дескрипторов функций.
Ответ 3
Я не думаю, что вы (или я) можете создавать динамические структуры данных в MATLAB. Мы должны использовать функции MATLAB OO и классы MATLAB. Поскольку я считаю, что эти средства действительно являются оболочкой MATLAB вокруг Java, я делаю смелое утверждение о том, что эти объекты находятся за пределами MATLAB. Я согласен с вопросом о семантике. Если вы хотите создавать динамические структуры данных с помощью MATLAB, вам нужно использовать OO и классы, вы не можете сделать это с тем, что я считаю основным языком, на котором не хватает указателей на уровне пользователя.
Ответ 4
Вы можете реализовать связанный список с дескриптором функции для вложенной функции, которая хранит данные связанного списка во вложенном родительском рабочем пространстве.
- Loren
Ответ 5
Создание связанного списка в MATLAB на самом деле не так уж плохо с новой объектно-ориентированной структурой. Я думаю, что большинство людей промахивается в том, что большинство действий указателя можно достичь в MATLAB с помощью "классов дескрипторов".
Итак, начните с класса Node...
classdef Node < handle
properties
next
prev
value
end
methods
function this = Node(inVal)
this.value = inVal;
end
end
end
Тогда ваш связанный класс списка будет выглядеть примерно так:
classdef LinkedList < handle
properties
firstNode
lastNode
end
methods
function this = LinkedList(newNode)
% Initialize LinkedList with newNode
this.firstNode = newNode;
this.lastNode = newNode;
end
function addNode(this,newNode)
% Add newNode to the end of the list
newNode.prev = this.lastNode;
this.lastNode.next = newNode;
this.lastNode = newNode;
end
end
end
Я выбросил это вместе довольно быстро, поэтому я не знаю, будет ли это работать так, как написано. Но если вам просто интересно, как будет выглядеть структура связанного списка MATLAB, я уверен, этого достаточно, чтобы вы начали.
Ключевым понятием здесь является суперкласс. Всякий раз, когда вы создаете класс типа handle
, вы получаете "указатель" на этот класс. Этот указатель может быть передан другим функциям или классам, что позволяет иметь узлы списка в других узлах.
Подробнее об этом можно узнать .
Ответ 6
Вы можете попробовать имитировать указатели, используя индексы. Это очень неудобный способ сделать это, но, как вы сказали, Matlab немного необычен и не может сделать "настоящий" связанный список.
Вы можете использовать структуру Matlab, состоящую из двух полей element
и next
. element
будет элементом списка, а next
будет индексом следующего node. Тогда вы можете иметь глобальный массив из них, представляющий вашу "память". Вы можете определить функцию "malloc", которая добавляет элемент в этот массив и возвращает его индекс. Затем у вас есть индекс head
, который является индексом первого элемента в списке, и вы можете соответствующим образом установить поля next
для формирования связанного списка.
Если вы действительно хотите сходить с ума, вы также можете реализовать free
и выполнить собственное управление памятью, отслеживая используемые и свободные узлы.
Ответ 7
Я немного смотрел функцию gnovice. Я думаю, что большинство wannts не является реальным связанным списком С++ (я думаю, вы можете сгенерировать связанный список только с классами в matlab), а просто общий объект, в котором вы можете хранить случайные массивы matlab. Из эскиза gnovice я создал следующее:
function listObject = listfuncs()
data = cell(0);
listObject = struct('display_list',@display_list,'listlength',@listlength,'add_firstelement',@add_firstelement,'add_firstelements',@add_firstelements,'add_lasttelement',@add_lasttelement,...
'add_lasttelements',@add_lasttelements,'add_element',@add_element,'add_elements',@add_elements,'set_element',@set_element,'delete_element',@delete_element,'delete_first',@delete_first,...
'delete_last',@delete_last,'GET_first',@GET_first,'GET_last',@GET_last,'GET',@GET);
function display_list
%# Displays the data in the list
disp(data);
end
function N = listlength
%# Numbers of elements in list
N = length(data);
end
function add_firstelement(datain)
%# Add an element first
data = [datain;data];
end
function add_firstelements(datain)
%# Add many element first
data = [datain(:);data];
end
function add_lasttelement(datain)
%# Add element last
data = [data;datain];
end
function add_lasttelements(datain)
%# Add many elements last
data = [data;datain(:)];
end
function add_element(datain,index)
%# Adds a set of data values after an index in the list, or at the end
%# of the list if the index is larger than the number of list elements
index = min(index,numel(data));
data = [data(1:index) datain data(index+1:end)];
end
function add_elements(datain,index)
%# Adds a set of data values after an index in the list, or at the end
%# of the list if the index is larger than the number of list elements
index = min(index,numel(data));
data = [data(1:index) datain(:) data(index+1:end)];
end
function set_element(datain,index)
%# function to just change element at position index
data{index} = datain;
end
function delete_element(index)
%# Deletes an element at an index in the list
if (index<=length(data) && index>0)
data(index) = [];
end
end
function delete_first()
%# Deletes fisrt element
data = data(2:end);
end
function delete_last()
%# Deletes fisrt element
data = data(1:end-1);
end
function dataout = GET_first()
%# get first element
dataout = data{1};
end
function dataout = GET_last()
%# get last element
dataout = data{end};
end
function dataout = GET(index)
%# get element at index here the cell can be transformed to standard arrays
dataout = cell2mat(data(index));
end
end
Я использую ячейки как данные, поэтому я могу хранить случайные объекты. Возможно, у некоторых из вас есть несколько более совершенных идей.