web-dev-qa-db-ja.com

MATLABリンクリスト

[〜#〜] matlab [〜#〜] でリンクリストを実装するためのいくつかの可能な方法は何ですか?

注:この質問は、実際的な価値ではなく、教育的な価値について尋ねています。 MATLABで実際にリンクリストをローリングしている場合、おそらく何かがおかしいと思います。ただし、私はこの学期にMATLABを集中的に使用するクラスの [〜#〜] ta [〜#〜] であり、この質問をする私の目標は、言語が良い。 MATLABの汎用プログラミング機能は少し変わっているので、このような疑問が理解に役立つと思います。

28
dsimcha

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オブジェクト。

24
Jason S

コメントで提案されている 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に格納される最初の「リンクリスト」になります。

次に、displayaddAfterdeleteの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を変更するかに注意してください。

この例を拡張して、リンクリストを操作する他の多数のネストされた関数を作成し、新しいフィールドを構造体に追加して、関数ハンドルを格納できます。

14
gnovice

新しいオブジェクト指向の構造では、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 をご覧ください。

5
Shaka

入れ子になった親のワークスペースにリンクリストのデータを保持する入れ子関数への関数ハンドルを使用して、リンクリストを実装できます。

-ローレン

4
Loren

あなた(または私)は、MATLABで動的データ構造を実行できないと思います。私たちは、MATLAB OO機能とMATLABクラスを使用する必要があります。これらの機能は、実際にはJavaの周りのMATLABラッパーであるため、は、MATLABの外にあります。セマンティクスの問題であると認めます。MATLABで動的データ構造を実行する場合は、OOとクラスを使用する必要があります。コア言語として、ユーザーレベルでのポインタが不足しています。

インデックスを使用してポインタのシミュレーションを試すことができます。これは非常に厄介な方法ですが、あなたが言ったように、Matlabは少し変わっており、「実際の」リンクされたリストを作成できません。

2つのフィールドelementnextで構成されるMatlab構造を使用できます。 elementはリストの要素であり、nextは次のノードのインデックスです。次に、「メモリ」を表すこれらのグローバル配列を持つことができます。この配列に要素を追加し、そのインデックスを返す「malloc」関数を定義できます。次に、リストの最初の要素のインデックスであるheadインデックスがあり、nextフィールドを適切に設定してリンクリストを形成できます。

本当に夢中になりたい場合は、freeを実装して、使用済みノードと空きノードを追跡することにより、独自の「メモリ管理」を行うこともできます。

2
Dima

私はノヴィスの機能を少し見てきました。私が最も望んでいるのは、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

セルをデータとして使用するので、ランダムなオブジェクトを格納できます。多分あなたのいくつかはいくつかの良いアイデアを持っています

0
jamk