MATLAB связанный список - PullRequest
       38

MATLAB связанный список

26 голосов
/ 12 сентября 2009

Каковы возможные способы реализации связанного списка в MATLAB ?

Примечание: я задаю этот вопрос для педагогической, а не практической ценности. Я понимаю, что если вы на самом деле катите свой собственный связанный список в MATLAB, вы, вероятно, делаете что-то не так. Тем не менее, я TA для класса, интенсивно использующего MATLAB в этом семестре, и моя цель задать этот вопрос - лучше понять общую структуру языка. Поскольку средства программирования MATLAB общего назначения немного необычны, я чувствую, что такой вопрос поможет мне понять их.

Ответы [ 7 ]

23 голосов
/ 14 сентября 2009

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, [D@66a917, Mr. Bill]

>> a.get(4)

ans =

     1
     2
     3
     4
     5

Единственным недостатком этого подхода является то, что у MATLAB нет способа маршалировать или сериализовать произвольные объекты MATLAB в Java, вы ограничены числами с плавающей запятой, целыми числами (необходимо приводить их в MATLAB, используя int8 и т. Д.), Логические значения, строки, массивы и объекты Java.

13 голосов
/ 14 сентября 2009

Ссылка 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.

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

5 голосов
/ 29 сентября 2009

Создание связанного списка в 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, вы получаете «указатель» на этот класс. Этот указатель может быть передан другим функциям или классам, что позволяет узлам списка указывать на другие узлы.

Вы можете узнать больше об этом здесь .

4 голосов
/ 14 сентября 2009

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

- Loren

3 голосов
/ 13 сентября 2009

Я не думаю, что вы (или я) можете создавать динамические структуры данных в MATLAB. Мы должны использовать возможности MATLAB OO и классы MATLAB. Поскольку я считаю, что эти средства действительно являются оболочкой MATLAB для Java, я смело заявляю, что эти средства находятся за пределами MATLAB. Вопрос семантики, я признаю. Если вы хотите создавать динамические структуры данных с MATLAB, вы должны использовать OO и классы, вы не можете делать это с тем, что я считаю базовым языком, в котором отсутствуют указатели на уровне пользователя.

2 голосов
/ 13 сентября 2009

Вы можете попробовать симулировать указатели, используя индексы. Это очень неловкий способ сделать это, но, как вы сказали, Matlab немного необычен и не может создать «реальный» связанный список.

Вы можете использовать структуру Matlab, состоящую из двух полей element и next. element будет элементом списка, а next будет индексом следующего узла. Тогда вы можете иметь глобальный массив из них, представляющий вашу «память». Вы можете определить функцию "malloc", которая добавляет элемент в этот массив и возвращает его индекс. Затем у вас есть индекс head, который является индексом первого элемента в списке, и вы можете соответствующим образом установить поля next для формирования связанного списка.

Если вы действительно хотите сойти с ума, вы также можете внедрить free и выполнить свое собственное «управление памятью», отслеживая используемые и свободные узлы.

0 голосов
/ 18 марта 2013

Я немного наблюдал за функцией gnovice. Я думаю, что в большинстве случаев это не реальный связанный список C ++ (я думаю, что вы можете создать связанный список только с классами в 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

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

...