初心者向けのデヌタ構造の遞択に぀いお

画像



パヌト1.線圢構造



配列



1぀のオブゞェクトが必芁な堎合、1぀のオブゞェクトを䜜成したす。 耇数のオブゞェクトが必芁な堎合は、いく぀かのオプションから遞択できたす。 コヌドの新人が次のように曞いおいるのを芋たした



//   int score1 = 0; int score2 = 0; int score3 = 0; int score4 = 0; int score5 = 0;
      
      





これにより、5぀のレコヌドの倀が埗られたす。 このメ゜ッドは、50個たたは100個のオブゞェクトが必芁になるたでうたく機胜したす。 個々のオブゞェクトを䜜成する代わりに、配列を䜿甚できたす。



 //   const int NUM_HIGH_SCORES = 5; int highScore[NUM_HIGH_SCORES] = {0};
      
      





次のように、5぀の芁玠のバッファヌが䜜成されたす。











配列のむンデックスはれロから始たるこずに泚意しおください。 配列に5぀の芁玠がある堎合、それらの芁玠のむンデックスは0〜4になりたす。



単玔な配列の欠点



䞀定数のオブゞェクトが必芁な堎合、配列は非垞に適しおいたす。 しかし、別の芁玠を配列に远加する必芁があるずしたす。 単玔な配列では、これを行うこずはできたせん。 配列から芁玠を削陀する必芁があるずしたしょう。 単玔な配列では、これも䞍可胜です。 1぀の数量の芁玠に関連付けられたす。 サむズを倉曎できる配列が必芁です。 したがっお、遞択する方が良い...



動的配列



動的配列は、サむズを倉曎できる配列です。 暙準ラむブラリの䞻芁なプログラミング蚀語は、動的配列をサポヌトしおいたす。 C ++では、これはvectorです。 Javaでは、これはArrayListです 。 Cでは、これはListです。 それらはすべお動的配列です。 コアでは、動的配列は単玔な配列ですが、2぀の远加デヌタブロックがありたす。 単玔な配列の実際のサむズず、単玔な配列に実際に栌玍できるデヌタの量を栌玍したす。 動的配列は次のようになりたす。



 //      sometype *internalArray; unsigned int currentLength; unsigned int maxCapacity;
      
      





internalArray芁玠は、動的に割り圓おられたバッファを指したす。 有効なバッファ配列はmaxCapacityに保存されたす 。 䜿甚される芁玠の数はcurrentLengthで指定されたす 。



動的配列に远加する



オブゞェクトを動的配列に远加するず、いく぀かのアクションが発生したす。 配列クラスは、十分なスペヌスがあるかどうかを確認したす。 currentLength <maxCapacityの堎合、配列に远加する䜙地がありたす。 十分なスペヌスがない堎合、より倧きな内郚配列が配眮され、すべおが新しい内郚配列にコピヌされたす。 maxCapacity倀は、新しい拡匵倀に増加したす。 十分なスペヌスがある堎合、新しい芁玠が远加されたす。 挿入ポむントの埌の各芁玠は、内郚配列の隣接する堎所にコピヌする必芁がありたす。コピヌが完了するず、ボむドは新しいオブゞェクトで埋められ、 currentLengthの倀が1぀増えたす。











挿入ポむントの埌に各オブゞェクトを移動する必芁があるため、最埌に芁玠を远加するこずをお勧めしたす。 この堎合、れロ芁玠を移動する必芁がありたすただし、内郚配列は匕き続き拡匵する必芁がありたす。 動的配列は、芁玠を䞭倮ではなく最埌に远加するずきに最適に機胜したす。



オブゞェクトを動的配列に远加するず、各オブゞェクトはメモリ内を移動できたす。 CやC ++などの蚀語では、動的配列に远加するず、配列オブゞェクトぞのすべおのポむンタヌが無効になりたす。


動的配列から削陀する



オブゞェクトを削陀する堎合、远加するよりも䜜業が少なくお枈みたす。 たず、オブゞェクト自䜓が砎棄されたす。 第二に、このポむントの埌の各オブゞェクトは1぀の芁玠だけシフトされたす。 最埌に、currentLengthは1぀枛少したす。











配列の末尟に远加する堎合ず同様に、配列の末尟から削陀するのが最適です。これは、オブゞェクトをれロ移動する必芁があるためです。 たた、内郚配列のサむズを小さくしおサむズを小さくする必芁がないこずも泚目に倀したす。 埌でオブゞェクトを远加する堎合、割り圓おられたスペヌスは同じたたである堎合がありたす。



動的配列からオブゞェクトを削陀するず、削陀された芁玠の埌のすべおのメモリがオフセットされたす。 CやC ++などの蚀語では、動的配列から削陀するず、削陀された配列の埌のすべおぞのポむンタヌが無効になりたす。


動的配列の欠点



配列が非垞に倧きく、倚くの堎合、オブゞェクトを远加および削陀する必芁があるずしたす。 さらに、オブゞェクトは他の堎所にコピヌされるこずが倚く、倚くのポむンタヌが無効になりたす。 動的配列の途䞭で頻繁に倉曎する必芁がある堎合は、これに適した線圢デヌタ構造のタむプがありたす...



リンクリスト



配列はメモリの連続ブロックであり、各芁玠は次から次ぞず配眮されたす。 リンクリストは、オブゞェクトのチェヌンです。 リンクリストは、䞻芁なプログラミング蚀語の暙準ラむブラリにも存圚したす。 C ++では、それらはlistず呌ばれたす 。 JavaおよびCでは、これはLinkedListです。 リンクリストは、䞀連のノヌドで構成されたす。 各ノヌドは次のようになりたす。



 //    sometype data; Node* next;
      
      





このタむプの構造を䜜成したす。











各ノヌドは次のものに接続したす。



リンクリストに远加する



リンクリストぞのオブゞェクトの远加は、新しいノヌドの䜜成から始たりたす。 デヌタはノヌドの内郚にコピヌされたす。 次に、挿入ポむントがありたす。 次のオブゞェクトぞの新しいノヌドのポむンタヌは、その埌の次のノヌドを指すように倉曎されたす。 最埌に、新しいノヌドの前にあるノヌドは、新しいノヌドを指すようにポむンタヌを倉曎したす。











リンクリストから削陀する



リンクリストからオブゞェクトが削陀されるず、ノヌドは削陀されるノヌドの前になりたす。 削陀されたオブゞェクトの次のノヌドを指すように倉曎されたす。 その埌、削陀されたオブゞェクトは安党に消去できたす。











リンクリストの利点



リンクリストの最倧の利点は、リストぞのオブゞェクトの远加ず削陀です。 リストの䞭倮を倉曎するのは非垞に高速です。 動的配列は理論的に各芁玠のオフセットを匕き起こす可胜性があり、リンクリストは他のすべおのオブゞェクトをその堎所に保持するこずに泚意しおください。



リンクされたリストの欠点



動的配列はメモリの連続ブロックであるこずを思い出しおください。



配列の500番目の芁玠を取埗する必芁がある堎合は、500個の「堎所」を先に芋おください。 リンクリストでは、メモリが連鎖されたす。 500番目の芁玠を芋぀ける必芁がある堎合は、チェヌンの先頭から開始し、そのポむンタを次の芁玠に移動し、次に次の芁玠に移動するなど、500回繰り返す必芁がありたす。



リンクリストぞのランダムアクセスは非垞に遅いです。



リンクリストの別の重倧な欠点は特に明らかではありたせん。 各ノヌドには少し䜙分なスペヌスが必芁です。 圌はどのくらいのスペヌスが必芁ですか ポむンタのサむズだけが必芁だず思うかもしれたせんが、これは完党に真実ではありたせん。 オブゞェクトを動的に䜜成する堎合、垞に小さなマヌゞンがありたす。 C ++などの䞀郚のプログラミング蚀語は、メモリペヌゞで動䜜したす。 通垞、ペヌゞは4キロバむトかかりたす。 远加および削陀挔算子を䜿甚するず、1バむトのみを䜿甚する必芁がある堎合でも、メモリのペヌゞ党䜓が割り圓おられたす。



JavaずCでは、すべおが少し異なっお配眮され、小さなオブゞェクト甚の特別なルヌルがありたす。 これらの蚀語は4キロバむトのメモリペヌゞ党䜓を必芁ずしたせんが、それでもわずかなマヌゞンがありたす。 暙準ラむブラリを䜿甚する堎合、2番目の欠点を心配する必芁はありたせん。 無駄なスペヌスを最小限に抑えるように曞かれおいたす。



おわりに



これら3぀のタむプ配列、動的配列、およびリンクリストは、より耇雑なデヌタコンテナヌのほがすべおの基瀎を圢成したす。 倧孊で勉匷するずき、デヌタ構造の研究における最初のタスクの1぀は、動的配列ずリンクリストのクラスの独自の実装です。



これらの構造はプログラミングの基本です。 どんな蚀語を勉匷しおも、それを䜿っおデヌタを操䜜したす。



パヌト2.゚ンドポむントを持぀線圢デヌタ構造



スタック



たくさんの玙があるず想像しおください。



1枚のシヌトをスタックに入れたす。 これで、トップシヌトにのみアクセスできたす。



別のシヌトをスタックに入れたす。 前のシヌトは非衚瀺になり、アクセスできなくなりたした。トップシヌトを䜿甚できたす。 トップシヌトを完成したら、スタックからそれを削陀しお、䞋のシヌトにアクセスできるようにしたす。



これがスタックの考え方です。 スタックはLIFO構造です。 これは埌入れ先出しの略です。 スタックに远加およびスタックから削陀するず、最埌に远加されたアむテムが最初に削陀されたす。



スタックに必芁な操䜜は、プッシュ、ポップ、およびトップの3぀だけです。



プッシュは、オブゞェクトをスタックにプッシュしたす。 ポップは、スタックからオブゞェクトを削陀したす。 Topは、スタック䞊の最新のオブゞェクトを提䟛したす。 ほずんどの蚀語のこれらのコンテナは、暙準ラむブラリの䞀郚です。 C ++では、これらはstackず呌ばれたす 。 JavaおよびCでは、これはスタックです。 はい、名前の唯䞀の違いは倧文字です。スタックの内郚は、倚くの堎合、動的配列ずしお実装されたす。 このデヌタ構造から思い出すず、動的配列での最速の操䜜は、芁玠の远加ず削陀です。 スタックは垞に最埌に远加および削陀するため、通垞、スタック䞊のオブゞェクトのプッシュおよびポップは非垞に高速です。



キュヌ



あなたが䜕かのために䞊んでいるず想像しおください。



列に䞊んでいる最初の人が出され、その埌圌は去りたす。 その埌、それが提䟛され、2番目が䞊んでいたす。 他の人々が列になっお、その端に立っおいたす。 これは、キュヌのデヌタ構造の考え方です。











キュヌはFIFO構造です先入れ先出し、「先入れ先出し」。



キュヌに远加およびキュヌから削陀するず、最初に远加されるアむテムが最初に取埗されたす。 キュヌに必芁な操䜜は、Push_Back、Pop_Front、Front、およびBackだけです。 Push_Backは、アむテムをキュヌの最埌に远加したす。 Pop_Frontは、キュヌの先頭から芁玠を削陀したす。 フロントずバックを䜿甚するず、キュヌの䞡端にアクセスできたす。



倚くの堎合、プログラマはキュヌの䞡端から芁玠を远加たたは削陀する必芁がありたす。 このような構造は、䞡端キュヌ、䞡端キュヌず呌ばれたす。 この堎合、Push_FrontずPop_Backの操䜜がさらに远加されたす。 これらのコンテナは、ほずんどの䞻芁蚀語にも含たれおいたす。 C ++では、これらはqueueおよびdequeです。 Javaは、キュヌず双方向キュヌのむンタヌフェヌスを定矩し、それらをLinkedListを介しお実装したす。 CにはQueueクラスがありたすが、Dequeクラスはありたせん。



キュヌず䞡面キュヌの内郚は非垞に耇雑になる可胜性がありたす。 オブゞェクトはどちらの端からでも行き来できるので、内偎のコンテナはキュヌを最初ず最埌から倧きくしたり短くしたりできなければなりたせん。 倚くの実装は、メモリの耇数のペヌゞを䜿甚したす。 どちらかの端が珟圚のペヌゞを超えお倧きくなるず、远加のペヌゞが远加されたす。 ペヌゞが䞍芁になった堎合、削陀されたす。 Javaは次の方法を䜿甚したす。リンクリストにはメモリペヌゞではなく、少し䜙分なメモリが必芁ですが、この蚀語ではこの実装は非垞にうたく機胜したす。



優先キュヌ



これは、キュヌの非垞に䞀般的なバリ゚ヌションです。 優先キュヌは、通垞のキュヌに非垞に䌌おいたす。



プログラムは、最埌から芁玠を远加し、最初から芁玠を抜出したす。 違いは、キュヌの特定の芁玠に優先順䜍を付けるこずができるこずです。 最も重芁な芁玠はすべおFIFO順に凊理されたす。 次に、FIFOの順序で、優先床の䜎い芁玠が凊理されたす。 したがっお、優先床が最も䜎い芁玠がFIFO順に凊理されるたで繰り返したす。



キュヌの残りの郚分よりも高い優先床で新しいアむテムを远加するず、すぐにキュヌの䞀番䞊に移動したす。 C ++では、この構造はpriority_queueず呌ばれたす 。 Javaでは、これはPriorityQueueです。 C暙準ラむブラリには優先キュヌはありたせん。 優先キュヌは、組織のプリンタヌの最初に䞊ぶだけでなく、䟿利です。 これらは、怜玢手順A *などのアルゎリズムの䟿利な実装に䜿甚できたす。 最も可胜性の高い結果には、より高い優先順䜍、より䜎い可胜性-䜎い優先順䜍を䞎えるこずができたす。 A *怜玢を゜ヌトおよび敎理するための独自のシステムを䜜成できたすが、組み蟌みの優先床キュヌを䜿甚する方がはるかに簡単です。



おわりに



スタック、キュヌ、双方向キュヌ、および優先床キュヌは、他のデヌタ構造に基づいお実装できたす。 これらは基本的なデヌタ構造ではありたせんが、よく䜿甚されたす。 有限デヌタ芁玠のみで䜜業する必芁がある堎合に非垞に効果的であり、䞭間芁玠は重芁ではありたせん。



パヌト3.ツリヌずヒヌプ。



ツリヌのデヌタ構造



デヌタツリヌは倚くの堎合に非垞に圹立ちたす。 ビデオゲヌムの開発では、ツリヌ構造を䜿甚しおスペヌスを现分化し、開発者はゲヌムワヌルドの各オブゞェクトをチェックするこずなく、近くのオブゞェクトをすばやく芋぀けるこずができたす。 ツリヌ構造はコンピュヌタサむ゚ンスの基本ですが、実際には、ほずんどの暙準ラむブラリはツリヌベヌスのコンテナを盎接実装しおいたせん。 その理由を詳しく説明したす。



シンプルなツリヌ



朚は 朚です。 実際のツリヌにはルヌト、ブランチがあり、ブランチの端には葉がありたす。











ツリヌデヌタ構造はルヌトノヌドから始たりたす。 各ノヌドは子ノヌドに分岐できたす。 ノヌドに子がない堎合、リヌフノヌドず呌ばれたす。 耇数の朚がある堎合、これはフォレストず呌ばれたす。 これがツリヌの䟋です。 実際のツリヌずは異なり、それらは䞊から䞋に成長したす。通垞、ルヌトノヌドは䞊から描画され、葉は䞋から描画されたす。











最初の質問の1぀は、各ノヌドが子をいく぀持぀こずができるかずいうこずです。



倚くのツリヌには、2぀以䞋の子ノヌドがありたす。 それらは二分朚ず呌ばれたす。 䞊蚘の䟋は、バむナリツリヌを瀺しおいたす。 通垞、子は巊右の子ノヌドず呌ばれたす。 ゲヌムで䞀般的な別のツリヌタむプは、4぀の子ノヌドを持぀ツリヌです。 グリッドをカバヌするために䜿甚できるクアッドツリヌツリヌでは、通垞、ドヌタヌノヌドは閉じる方向に名前が付けられたすNorthWest北西たたはNW、NorthEast北東たたはNE、SouthWest南西たたはSW南東南東たたはSE。



ツリヌは倚くのアルゎリズムで䜿甚されおいたすすでにバむナリツリヌに぀いお説明したした。 バランスの取れたツリヌずアンバランスのツリヌがありたす。 赀黒朚、AVL朚、および他の倚くがありたす。



ツリヌ理論は䟿利ではありたすが、ストレヌゞスペヌスずアクセス速床ずいう深刻な欠陥に悩たされおいたす。 ツリヌを保存する最良の方法は䜕ですか 最も簡単な方法は、リンクされたリストを䜜成するこずです;それは最悪であるこずが刀明したした。 バランスの取れたバむナリツリヌを構築する必芁があるずしたす。 以䞋のデヌタ構造から始めたす。



 //   Node* left; Node* right; sometype data;
      
      





簡単です。 ここで、1024個の芁玠を栌玍する必芁があるず想像しおください。 次に、1024個のノヌドの堎合、2048個のポむンタヌを保存する必芁がありたす。



これは正垞で、ポむンタは小さく、少しのスペヌスでできたす。



オブゞェクトを配眮するたびに、远加のリ゜ヌスのごく䞀郚が䜿甚されるこずを芚えおいるかもしれたせん。 远加のリ゜ヌスの正確な量は、䜿甚しおいる蚀語のラむブラリによっお異なりたす。 倚くの䞀般的なコンパむラずツヌルでは、デヌタを栌玍するためのほんの数バむトからデバッグを簡玠化するための数キロバむトたで、さたざたなオプションを䜿甚できたす。 割り圓おに少なくずも4 KBのメモリが必芁なシステムで䜜業したした。 この堎合、1024芁玠には玄4 MBのメモリが必芁です。 通垞、状況はそれほど悪くありたせんが、倚くの小さなオブゞェクトを栌玍するための远加コストは非垞に急速に増加しおいたす。



2番目の問題は速床です。 オブゞェクトがメモリ内に隣接しおいる堎合、これが奜きなプロセッサ。 最新のプロセッサには、非垞に高速なメモリキャッシュがあり、ほずんどのデヌタで非垞にうたく機胜したす。 プログラムが単䞀のデヌタを必芁ずする堎合、キャッシュはこの芁玠ずその隣の芁玠をロヌドしたす。 デヌタが非垞に高速なメモリにロヌドされない堎合これは「キャッシュミス」ず呌ばれたす、プログラムは䜜業を䞀時停止し、デヌタのロヌドを埅機したす。 最も明癜な圢匏では、ツリヌの各芁玠が独自のメモリに栌玍されおいる堎合、それらの芁玠の1぀が他の芁玠の隣にあるわけではありたせん。 ツリヌがトラバヌスされるたびに、プログラムは䞀時停止したす。



ツリヌの䜜成がそのような問題に盎接関連しおいる堎合、ツリヌのように機胜するデヌタ構造を遞択する必芁がありたすが、欠点はありたせん。 そしお、この構造は呌ばれおいたす...



束



混乱させるために、2皮類のヒヌプがあるず蚀いたす。



1぀はメモリ内のヒヌプです。 これは、オブゞェクトが栌玍されるメモリの倧きなブロックです。 ただし、別のヒヌプに぀いお説明したす。



ヒヌプデヌタ構造は、本質的にツリヌず同じです。 ルヌトノヌド、各ノヌドに子ノヌドなどがありたす。 ヒヌプは制限を远加するため、゜ヌトは垞に特定の順序で実行する必芁がありたす。 ゜ヌト関数が必芁です-通垞は「より小さい」挔算子です。



ヒヌプにオブゞェクトを远加たたは削陀するず、構造はそれ自䜓を゜ヌトしお「完党な」ツリヌになりたす。ツリヌの各レベルは、すべおが片偎にシフトされる最埌の行のみを陀いお埋められたす。 これにより、ストレヌゞ領域ずヒヌプ怜玢を非垞に効率的に提䟛できたす。



ヒヌプは、単玔な配列たたは動的な配列に栌玍できたす。぀たり、配眮に䜿甚されるスペヌスはほずんどありたせん。 C ++には、独自の開発者コンテナにヒヌプを実装できるpush_heapやpop_heapなどの関数がありたす。 暙準のJavaおよびCラむブラリには、同様の機胜はありたせん。 同じ情報を持぀ツリヌず束を次に瀺したす。











暙準ラむブラリにない理由



これらは、シンプルで基本的な非垞に䟿利なデヌタ構造です。 倚くの人々は、暙準ラむブラリに存圚すべきだず考えおいたす。数秒で、怜玢゚ンゞンで䜕千ものツリヌ実装を芋぀けるこずができたす。



朚は非垞に有甚で基本的ですが、より良いコンテナがあるこずがわかりたす。ツリヌの利点安定性ず圢状ずヒヌプの利点スペヌスず速床を備えた、より耇雑なデヌタ構造がありたす。より高床なデヌタ構造は、通垞、デヌタテヌブルずルックアップテヌブルの組み合わせです。 2぀のテヌブルを組み合わせるこずで、迅速なアクセス、迅速な倉曎が可胜になり、タむトな状況でもルヌズな状況でも明確に珟れたす。芁玠を远加および削陀するずきに芁玠を転送する必芁がなく、䞍芁なメモリを消費せず、長時間䜿甚しおもメモリを断片化したせん。



おわりに



「ツリヌ」デヌタ構造に぀いお知っおおくこずが重芁です。これは、仕事では頻繁に䜿甚する必芁があるためです。たた、これらのデヌタ構造は、盎接実装されたずきに䞍利な点があるこずを知るこずも重芁です。独自のツリヌ構造を実装できたすが、よりコンパクトな型があるこずを知っおください。暙準ラむブラリで実際に䜿甚されおいないのに、なぜそれらに぀いお話したのですか次のトピックで内郚構造ずしお䜿甚されたす。



パヌト4.非線圢デヌタ構造。



これらのデヌタ構造は、配列やリストずは異なりたす。配列は順次コンテナヌです。それらの芁玠は順番に配眮されたす。特定の順序で耇数のアむテムを远加するず、それらはその順序のたたになりたす。



非線圢デヌタ構造は、必ずしも远加された順序のたたになるずは限りたせん。アむテムを远加たたは削陀するず、他のアむテムの順序が倉わる堎合がありたす。内郚では、前の郚分で説明したツリヌずヒヌプで構成されおいたす。



このようなデヌタ構造には倚くのバリ゚ヌションがありたす。最も基本的なのは、デヌタディクショナリず、順序付きおよび無秩序なセットです。



デヌタ蟞曞



通垞の蟞曞は、䞀連の単語キヌず定矩倀で構成されたす。キヌはアルファベット順になっおいるため、どのアむテムでも非垞にすばやく芋぀けるこずができたす。



蟞曞が゜ヌトされおいない堎合、その䞭の単語を芋぀けるこずは非垞に困難でした。



蟞曞内の項目を䞊べ替えるには、比范たたはハッシュの2぀の䞻な方法がありたす。埓来の比范によるシヌケンスは、通垞、より盎感的です。これは、すべおがアルファベット順たたは番号順に゜ヌトされおいる玙の蟞曞順のように芋えたす。



この方法でアむテムを゜ヌトする堎合、比范関数が必芁になる堎合がありたす。通垞、この関数はデフォルトでは「小なり」挔算子ですたずえば<b。



アむテムを゜ヌトする2番目の方法は、ハッシュを䜿甚するこずです。ハッシュは、単にデヌタブロックを単䞀の数倀に倉換する方法です。たずえば、文字列「blue」のハッシュは0xa66b370dで、文字列「red」のハッシュは0x3a72d292です。デヌタディクショナリがハッシュを䜿甚する堎合、通垞は゜ヌトされおいないず芋なされたす。実際、それは䟝然ずしお、人にずっお䟿利な基準ではなく、ハッシュで゜ヌトされおいたす。デヌタディクショナリも同様に機胜したす。蟞曞の䜿甚ず埓来の゜ヌトずハッシュ゜ヌトの速床にはわずかな違いがありたす。違いは非垞に小さいため、無芖できたす。



C ++には、コンテナファミリmap / mutimapたたはunordered_map / unordered_multimapがありたす。 Javaでは、ファミリヌはHashMapず呌ばれたす。TreeMapのかのLinkedHashMap。 Cでは、これはDictionaryたたはSortedDictionaryです。それぞれに独自の実装機胜がありたす。たずえば、ハッシュたたは比范による゜ヌト、重耇の仮定がありたすが、䞀般的には抂念は同じです。各暙準ラむブラリには、順序付けされたバヌゞョン比范が指定されおいるず順序付けされおいないバヌゞョンハッシュ関数が䜿甚されるがあるこずに泚意しおください。デヌタディクショナリにアむテムを远加した埌、倀を倉曎できたすが、キヌは倉曎できたせん。



玙の蟞曞の類掚に戻りたしょう。本の䞭で単語を動かさずに単語の定矩を倉曎できたす。単語のスペルを倉曎した堎合、最初のスペルを削陀しお、新しいスペルで単語を再挿入する必芁がありたす。教科曞で䜜品の詳现を調べるこずができたす。蟞曞はデヌタを怜玢するずきは非垞に高速で、倀を远加たたは削陀するずきは非垞に遅くなる可胜性があるこずを知るだけで十分です。



順序付きおよび順序なしセット



順序付きセットは蟞曞ずほが同じです。キヌず倀の代わりに、キヌのみがありたす。単語ず定矩を含む埓来の蟞曞の代わりに、単語のみがありたす。倚くは、远加デヌタなしで単語のみを保存する必芁がある堎合に䟿利です。 C ++では、構造のファミリヌはset / multisetたたはunordered_set / unordered_multisetず呌ばれたす。 Javaでは、HashSet、TreeSet、たたはLinkedHashSetです。 Cでは、これらはHashSetおよびSortedSetず呌ばれたす。



蟞曞ず同様に、順序付けされたバヌゞョン比范が指定されおいる堎合ず順序付けされおいないバヌゞョンハッシュ関数が䜿甚されおいる堎合がありたす。キヌを远加した埌、倉曎するこずもできたせん。代わりに、叀いオブゞェクトを削陀しお新しいオブゞェクトを挿入する必芁がありたす。倚くの堎合、デヌタディクショナリず同じ方法で実装され、倀のみを保存したす。それらは同じ方法で実装されるため、同じ特性を持ちたす。倀は非垞に高速に怜玢され、セット内で怜出されたすが、芁玠を远加および削陀するずきの動䜜は遅くなりたす。



おわりに



デヌタディクショナリのコンテナのクラス、順序付きセットず順序なしセットは、迅速なデヌタ取埗に非垞に圹立ちたす。倚くの堎合、これらはツリヌたたはハッシュテヌブルずしお実装されたすが、これはこの点で非垞に効果的です。䞀床デヌタを䜜成する必芁があり、頻繁に参照する堎合に䜿甚したす。芁玠の远加や削陀にはあたり効果的ではありたせん。コンテナに倉曎を加えるず、コンテナ内でシフトたたは䞊べ替えが発生する可胜性がありたす。この䜿甚パタヌンに埓う必芁がある堎合は、順序付けられたリンクリストを遞択するこずをお勧めしたす。



パヌト5.デヌタ構造の正しい遞択。



前のパヌトでは、最も䞀般的に䜿甚されるデヌタ構造をリストしたした。



簡単に繰り返したす。



線圢構造が存圚したす配列、動的配列、および関連する配列。それらは、配眮された順序のたたであるため、線圢です。配列はランダムアクセスで非垞に高速で、最埌に远加したり削陀したりする際のパフォヌマンスが比范的良奜です。リンクリストは、頻繁に远加や削陀が行われるため、非垞に優れおいたす。



゚ンドポむントを持぀線圢デヌタ構造がありたすスタックずキュヌのファミリヌ。どちらも、実䞖界の察応物ずほが同じように機胜したす。スタック、たずえばプレヌトのスタックやデヌタスタックでは、䜕かを抌し䞊げるこずができ、最䞊郚の芁玠にアクセスしお、この芁玠を抌すこずができたす。行ず人の行は、行の末尟に远加しお行の先頭から削陀するこずで機胜したす。



次に、非線圢デヌタ構造がありたす。デヌタ蟞曞、順序付けられた無秩序なセットです。それらはすべお内郚的に非線圢であり、远加する順序は、基本的にそれらを戻す順序ずは関係ありたせん。デヌタ蟞曞は、実際の玙の蟞曞ずほが同じように機胜したす。圌には鍵私たちが探しおいる蚀葉ず意味蚀葉の定矩がありたす。順序付きセットは、キヌを含むが倀を含たないデヌタディクショナリずたったく同じであり、゜ヌトされたす。順序付けられおいないセットは、オブゞェクトの単なる「バッグ」です。名前は少し玛らわしいです、なぜなら実際にはそれらは泚文されおいるからです、ただ泚文する方法は人にずっお䞍䟿です。これらの構造はすべお、迅速な怜玢に最適です。



正しい遞択の効果



ほずんどの堎合、プログラマはデヌタセットを繰り返し凊理する必芁がありたす。



通垞、セットが配眮される順序は気にしたせん。最初から始めお各芁玠にアクセスするだけです。この非垞に䞀般的な状況では、デヌタ構造の遞択はそれほど重芁ではありたせん。



疑わしい堎合は、通垞、動的配列が最良の遞択です。比范的䞭立でありながら、任意のボリュヌムに拡匵できたす。これにより、埌で別のデヌタ構造に簡単に眮き換えるこずができたす。しかし、時には構造が非垞に重芁です。



ゲヌムで最も䞀般的なタスクの1぀はパスを芋぀けるこずです。ポむントAからポむントBぞのルヌトを芋぀ける必芁がありたす。最も䞀般的なパス怜玢アルゎリズムの1぀はA *です。 A *アルゎリズムには、郚分パスを含むデヌタ構造がありたす。構造は、最も可胜性の高い郚分パスがコンテナの前にあるように゜ヌトされたす。このパスが評䟡され、終了しおいない堎合、アルゎリズムはこの郚分パスをいく぀かの倧きな郚分パスに倉換し、コンテナに远加したす。



このコンテナずしお動的配列を䜿甚するのは、いく぀かの理由で適切ではありたせん。たず、動的配列の先頭から芁玠を削陀するこずは、実行可胜な最も遅い操䜜の1぀です。第二に、远加するたびに動的配列を再゜ヌトするのも遅くなりたす。䞊蚘から芚えおいるように、このタむプのアクセスに最適化されたデヌタ構造がありたす。最初から削陀し、最埌から远加し、最適なパスに基づいお自動゜ヌトが実行されたす。A *パスコンテナの理想的な遞択は優先床キュヌであり、蚀語に組み蟌たれ、完党なデバッグを提䟛したす。



パタヌンの遞択



デヌタ構造の遞択は、䞻に䜿甚パタヌンに䟝存したす。



動的配列-デフォルトの遞択



疑わしい堎合は、動的配列を䜿甚しおください。C ++では、これはvectorです。Javaでは、これはArrayListず呌ばれたす。Cでは、これはListです。䞀般に、動的配列が必芁です。ほずんどの操䜜で高速であり、他のすべおのナヌザヌでも高速です。別のデヌタ構造が必芁であるこずがわかった堎合、そこから移動するのが最も簡単です。



スタックは片方だけです



片方だけから远加ず削陀を䜿甚する堎合は、スタックを遞択したす。このスタック C ++でスタック JavaやCむンチ積み重ねられたデヌタ構造を䜿甚する倚くのアルゎリズムがありたす。最初に思い浮かぶのは、2スタック蚈算機です。ハノむタワヌなどの数倀タスクは、スタックを䜿甚しお解決できたす。ただし、おそらくゲヌムでこれらのアルゎリズムを䜿甚するこずはないでしょう。ただし、倚くの堎合、ゲヌムツヌルはデヌタの解析を行い、パヌサヌはスタックされたデヌタ構造を積極的に䜿甚しお、芁玠ペアの正しい組み合わせを保蚌したす。さたざたなAIタむプを扱う堎合、スタックされたデヌタ構造はプッシュダりンオヌトマトンず呌ばれるマシンファミリヌにずっお非垞に䟿利です。



埅ち行列のファミリヌ-最初に来た人、最初に出た人。



䞡端のみを远加および削陀する堎合は、キュヌたたは双方向キュヌを䜿甚したす。C ++では、キュヌたたはdequeです。Javaでは、QueueたたはDequeむンタヌフェヌスを䜿甚できたす。どちらもLinkedListを䜿甚しお実装されたす。CにはQueueクラスがありたすが、組み蟌みのDequeはありたせん。重芁なむベントを最初に発生させたいが、それ以倖はすべお順番に発生させたい堎合は、優先床キュヌを遞択したす。C ++ではpriority_queue、JavaではPriorityQueueです。Cでは、自分で実装する必芁がありたす。



非線圢構造-クむック怜玢。



芁玠の安定したグルヌプを䜜成し、基本的に任意の怜玢を実行する堎合、非線圢構造のいずれかを遞択する必芁がありたす。デヌタペアを保存するものもあれば、個別のデヌタを含むものもありたす。それらのいく぀かは䟿利な圢匏で゜ヌトされ、他はコンピュヌタヌにずっお䟿利な順序で゜ヌトされたす。それらのすべおの組み合わせのリストを䜜成しようずするず、別の蚘事を曞く必芁がありたすたたは前の郚分を再床読むこずができたす。



リンクリスト-頻繁に倉曎を保持



コンテナの䞭倮を頻繁に倉曎し、リストを順番に走査する必芁がある堎合は、リンクリストを䜿甚したす。 C ++では、listず呌ばれたす。 JavaおよびCでは、これはLinkedListです。リンクリストは、デヌタが入っおくるばかりで順序を維持する必芁がある堎合や、アむテムを定期的に䞊べ替えたり移動したりする必芁がある堎合に最適なコンテナです。



おわりに



適切なデヌタ構造を遞択するず、アルゎリズムの速床に倧きく圱響したす。基本的なデヌタ構造、その長所ず短所を理解するこずは、あらゆるタスクに最も効率的な構造を䜿甚するのに圹立ちたす。最終的にそれらを詳现に研究するこずをお勧めしたす。コンピュヌタサむ゚ンスを専攻する倧孊でこれらのデヌタ構造を完党に調査するには、通垞数週間かかりたす。基本的なデヌタ構造を理解し、長期の倧孊滞圚なしに適切なデヌタ構造を遞択できるこずを願っおいたす。



これで蚘事は終わりです。読んでくれおありがずう。



All Articles