Связанный список 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

Я использую ячейки как данные, поэтому я могу хранить случайные объекты. Возможно, у некоторых из вас есть несколько более совершенных идей.