web-dev-qa-db-fra.com

Liste liée MATLAB

Quels sont quelques moyens possibles de mettre en place une liste liée dans MATLAB ?

Remarque: je pose cette question à la valeur pédagogique, pas de valeur pratique. Je me rends compte que si vous roulez réellement votre propre liste liée à Matlab, vous faites probablement quelque chose de mal. Cependant, je suis un [~ # ~ # ~] ta [~ # ~] Pour une classe matlab-intensive, ce semestre et mon objectif de poser cette question est de comprendre la structure générale de la la langue meilleure. Alors que les installations de programmation à usage général de Matlab sont un peu inhabituelles, je ressens une question comme celle-ci m'aidera à les comprendre.

28
dsimcha

Matlab a accès à 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

L'un des inconvénients de cette approche est que Matlab n'a pas de moyen de maréchaler ou de sérialiser des objets de matlab arbitraires dans Java, vous êtes limité à numéros de points flottants, entiers (besoin de les jeter dans MATLAB en utilisant int8 etc.), des booléens, des chaînes, des tableaux et Java objets.

24
Jason S

Le linkLUL suggéré dans les commentaires est probablement le choix que je voudrais faire si je voulais mettre en œuvre une liste liée à Matlab. Cependant, cette approche s'arrêtait dans les caractéristiques orientées objet de Matlab, ce qui pourrait ne pas être ce que vous voulez, car vous avez mentionné de vouloir mieux "comprendre la structure générale de la langue". En tant que tel, vous pouvez faire mieux avec un exemple plus simple qui intègre des caractéristiques générales de base de la programmation MATLAB.

Un certain nombre de fonctionnalités générales ont été mentionnées dans d'autres réponses, telles que matrices et indexation matricielle , création de structures et utilisation fonctions imbriquées et - poignées de fonction . Je vais passer par un exemple qui utilise toutes ces fonctionnalités et espérons-le donne une belle introduction à un certain nombre de concepts clés de Matlab ...

Exemple de code:

Enregistrez le code ci-dessous dans un fichier appelé linked_list.m sur le chemin 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

La description:

La fonction linked_list Accepte une matrice de taille arbitraire et la résout d'abord dans un vecteur de ligne à l'aide de REMODAPE Fonction. Cela devient la "liste liée" initiale, stockée dans la variable data.

Ensuite, une structure est créée (à l'aide de la structure [~ # ~ ~] [~ # ~] Fonction) qui a trois éléments: display, addAfter, et delete. Chacun de ces champs stocke une poignée de fonction à l'une des trois fonctions imbriquées dans la fonction mère linked_list. Ces fonctions imbriquées peuvent accéder à la variable data stockée dans la fonction mère.

La structure listObject est renvoyée de linked_list. Tant que cette structure existe dans l'espace de travail, et donc tant que les poignées de fonction contiennent existent, la variable data doit persistera même après la fonction linked_list Retour. Nous pouvons ensuite invoquer les fonctions imbriquées (à l'aide de leurs poignées) pour modifier la variable data. Voici un exemple ...

Tout d'abord, créez une liste liée "objet" et affiche le contenu:

>> 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

Ensuite, ajoutez un élément "4" après l'élément de la deuxième liste et affichez:

>> listObj.addAfter(4,2)  %# Access the `addAfter` field and invoke the function
>> listObj.display()
     1     2     4     3

Et enfin, supprimez le deuxième élément de liste et afficher:

>> listObj.delete(2)  %# Access the `delete` field and invoke the function
>> listObj.display()
     1     4     3

Notez comment les fonctions imbriquées add_element et delete_element utiliser indexation matricielle pour modifier la variable data.

Vous pouvez étendre cet exemple pour créer de nombreuses autres fonctions imbriquées pour fonctionner sur une liste liée, en ajoutant de nouveaux champs à la structure pour stocker leurs poignées de fonction.

14
gnovice

Créer une liste liée à Matlab n'est pas vraiment trop mauvaise avec la nouvelle structure orientée objet. Je pense que la plupart des gens manquent est que la plupart des comportements du pointeur peuvent être atteints dans Matlab grâce à l'utilisation de "classes de poignée".

Donc, commencez par un Node classe ...

classdef Node < handle

       properties
           next
           prev
           value
       end

       methods
            function this = Node(inVal)
                this.value = inVal;
            end
       end
 end 

Ensuite, votre classe de liste liée ressemblerait à quelque chose comme ça ...

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

J'ai jeté cela ensemble assez rapidement pour que je ne sais pas si cela fonctionnera comme écrit. Mais si vous êtes juste intéressé par la structure d'une liste liée matlab à ressembler, je suis sûr que cela suffit à vous aider à démarrer.

Le concept de clé ici est la superclasse de la poignée. Chaque fois que vous créez une classe de type handle, vous obtenez un "pointeur" à cette classe. Ce pointeur peut être transmis à d'autres fonctions ou classes permettant ainsi de disposer des nœuds du point de liste à d'autres nœuds.

Vous pouvez en savoir plus sur cela ici .

5
Shaka

Vous pouvez implémenter une liste liée avec une poignée de fonction à une fonction imbriquée qui conserve les données de la liste liées dans l'espace de travail de la mère imbriquée.

- -loren

4
Loren

Je ne pense pas que vous (ou i) peut faire des structures de données dynamiques 'dans' Matlab. Nous devons utiliser MATLAB OO Caractéristiques et classes Matlab. Depuis que je pense que ces installations sont vraiment une wrapper Matlab autour Java Je fais la revendication audacieuse que ces installations sont en dehors de Matlab. Une question de sémantique, je concède. Si vous souhaitez effectuer des structures de données dynamiques avec MATLAB, vous devez utiliser OO et classes, vous ne pouvez pas le faire avec ce que je pense comme la langue principale, qui manque de pointeurs au niveau de l'utilisateur.

3

Vous pouvez essayer de simuler des pointeurs en utilisant des indices. C'est une façon très délicate de le faire, mais comme vous l'avez dit, MATLAB est un peu inhabituel et ne peut pas faire une "vraie" liste liée.

Vous pouvez utiliser une structure MATLAB composée de deux champs element et next. element _ serait l'élément de la liste et next serait l'index du nœud suivant. Ensuite, vous pouvez avoir un tableau global de ceux-ci, représentant votre "mémoire". Vous pouvez définir la fonction "MALLOC" qui ajoute un élément à ce tableau et renvoie son index. Ensuite, vous avez un indice head qui est l'index du premier élément de la liste et vous pouvez définir les champs next de manière appropriée pour former une liste liée.

Si vous voulez vraiment devenir fou, vous pouvez également implémenter un free et faire votre propre "gestion de la mémoire" en gardant une trace des nœuds usagés et libres.

2
Dima

J'ai regardé un peu la fonction de gnovice. Je pense que ce que la plupart des wannts n'est pas une liste liée réelle de C++ (je pense que vous pouvez générer une liste liée uniquement avec des classes dans Matlab), mais juste un objet général où vous pouvez stocker des tableaux de matelab aléatoire. De l'esquisse de Gnovice, j'ai généré ce qui suit:

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

J'utilise des cellules comme des données afin que je puisse stocker des objets aléatoires. Peut-être que certains d'entre vous ont des idées de bétail

0
jamk