[〜#〜] matlab [〜#〜] でリンクリストを実装するためのいくつかの可能な方法は何ですか?
注:この質問は、実際的な価値ではなく、教育的な価値について尋ねています。 MATLABで実際にリンクリストをローリングしている場合、おそらく何かがおかしいと思います。ただし、私はこの学期にMATLABを集中的に使用するクラスの [〜#〜] ta [〜#〜] であり、この質問をする私の目標は、言語が良い。 MATLABの汎用プログラミング機能は少し変わっているので、このような疑問が理解に役立つと思います。
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に変換する方法がないため、 浮動小数点数、整数(int8
などを使用してMATLABでキャストする必要がある)に制限されます。 )、ブール値、文字列、配列、およびJavaオブジェクト。
コメントで提案されている linkLul は、MATLABでリンクリストを実装する場合におそらく選択するでしょう。ただし、このアプローチは、MATLABのオブジェクト指向機能に迷い込んでしまい、「言語の一般的な構造をよりよく理解したい」と述べたので、これは望ましいものではないかもしれません。そのため、MATLABプログラミングの一般的なコア機能を組み込んだより簡単な例を使用する方がよいでしょう。
行列と行列のインデックス 、 構造の作成 、および ネストされた関数 と-の使用など、他の多くの一般的な機能が他の回答で言及されています 関数ハンドル 。これらのすべての機能を利用する例を紹介し、うまくいけばMATLABのいくつかの主要な概念を紹介します...
以下のコードを、MATLABパス上のlinked_list.m
というファイルに保存します。
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
に格納される最初の「リンクリスト」になります。
次に、display
、addAfter
、delete
の3つの要素を持つ構造体が作成されます( [〜#〜] struct [〜#〜] 関数を使用)。これらの各フィールドは、親関数内にネストされたである3つの関数の1つに 関数ハンドル を格納します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
次に、2番目のリスト要素の後に要素「4」を追加して表示します。
>> listObj.addAfter(4,2) %# Access the `addAfter` field and invoke the function
>> listObj.display()
1 2 4 3
最後に、2番目のリスト要素を削除して表示します。
>> listObj.delete(2) %# Access the `delete` field and invoke the function
>> listObj.display()
1 4 3
ネストされた関数add_element
およびdelete_element
がどのように matrix indexing を使用して変数data
を変更するかに注意してください。
この例を拡張して、リンクリストを操作する他の多数のネストされた関数を作成し、新しいフィールドを構造体に追加して、関数ハンドルを格納できます。
新しいオブジェクト指向の構造では、MATLABでリンクリストを作成することはそれほど悪くありません。ほとんどの人が見落としているのは、ほとんどのポインターの動作が「ハンドルクラス」を使用してMATLABで実現できることです。
したがって、Node class ...
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
のクラスを作成すると、そのクラスへの「ポインター」が取得されます。そのポインターは他の関数またはクラスに渡すことができるため、リストのノードが他のノードを指すようにすることができます。
この詳細については here をご覧ください。
入れ子になった親のワークスペースにリンクリストのデータを保持する入れ子関数への関数ハンドルを使用して、リンクリストを実装できます。
-ローレン
あなた(または私)は、MATLABで動的データ構造を実行できないと思います。私たちは、MATLAB OO機能とMATLABクラスを使用する必要があります。これらの機能は、実際にはJavaの周りのMATLABラッパーであるため、は、MATLABの外にあります。セマンティクスの問題であると認めます。MATLABで動的データ構造を実行する場合は、OOとクラスを使用する必要があります。コア言語として、ユーザーレベルでのポインタが不足しています。
インデックスを使用してポインタのシミュレーションを試すことができます。これは非常に厄介な方法ですが、あなたが言ったように、Matlabは少し変わっており、「実際の」リンクされたリストを作成できません。
2つのフィールドelement
とnext
で構成されるMatlab構造を使用できます。 element
はリストの要素であり、next
は次のノードのインデックスです。次に、「メモリ」を表すこれらのグローバル配列を持つことができます。この配列に要素を追加し、そのインデックスを返す「malloc」関数を定義できます。次に、リストの最初の要素のインデックスであるhead
インデックスがあり、next
フィールドを適切に設定してリンクリストを形成できます。
本当に夢中になりたい場合は、free
を実装して、使用済みノードと空きノードを追跡することにより、独自の「メモリ管理」を行うこともできます。
私はノヴィスの機能を少し見てきました。私が最も望んでいるのは、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
セルをデータとして使用するので、ランダムなオブジェクトを格納できます。多分あなたのいくつかはいくつかの良いアイデアを持っています