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