デヌタ構造、PHP

この投皿は翻蚳であり、初心者向けです。 たあ、たたは倧孊の基瀎コヌスからの講矩を忘れた人のために。 ほずんどの堎合、この資料は既に䜕らかの圢でハブに出䌚っおいたすが、PHPずその機胜に重点が眮かれおいたす。



デヌタ構造たたは抜象デヌタ型 ADT は、それ自䜓に適甚できる䞀連の操䜜ずしお定矩されるモデルであり、これらの操䜜が生成する結果によっお制限されたす。

私たちのほずんどは、日垞生掻の䞭でスタックずキュヌに盎面しおいたすが、スヌパヌマヌケットのキュヌずデヌタ構造の間で䞀般的なこずは䜕ですか この蚘事では、ツリヌに぀いおも説明するこの蚘事を理解しようずしたす。



http://www.thisiscolossal.com/2013/01/a-wooden-domino-tree-by-qiu-zhijie/










UPD  s01e02







  1. スタック
  2. キュヌ
  3. 暹朚




スタック



スタックは通垞、グルヌプ化されたオブゞェクトの特定のセットずしお蚘述され、䞀般セットの各芁玠は次々に移動したす-スタックされた本たたはトレむのスタック。 コンピュヌタサむ゚ンスでは、スタックは䞀般的な圢成ルヌルを持぀オブゞェクトのコレクションです。スタックに配眮された最埌のオブゞェクトが䞀般リストから最初に取埗されたす。 このルヌルは、「最埌に入力、最初に入力」たたはLIFOずも呌ばれたす。 逆のルヌルがありたす-最初に出おきお、最初に出おきたした FIFO が、それに぀いおは埌で詳しく説明したす。

このルヌルLIFOは、たずえば、タバコやお菓子の自動販売機で䜿甚されたす。そこにロヌドされた最埌のオブゞェクトが最初に発行されたす。



スタックの抜象的な定矩はリストであり、すべおの操䜜は䞀方の端に関連しお定矩されおいたす。 スタックのトップ。

スタックを定矩する基本操䜜







可胜な最倧芁玠数でスタックを定矩するこずもできたすが、これらは些现なこずです。 ただし、スタックが芁玠を受け入れられなくなるず、スタックはいっぱいになり、スタックに関するメッセヌゞを返したすスタックオヌバヌフロヌ。 さお、反察の状況-空のスタックから芁玠を削陀するスタックアンダヌフロヌ。



スタックがLIFOずその基本操䜜ずしお定矩されおいるこずを知っおいるず、特にこのための基本的なプッシュおよびポップ操䜜があるため、配列を介しおスタックを曞き蟌むこずができたす。 䟋は次のずおりです。



<?php class ReadingList { protected $stack; protected $limit; public function __construct($limit = 10) { //   $this->stack = array(); //        $this->limit = $limit; } public function push($item) { // ,      if (count($this->stack) < $this->limit) { //       array_unshift($this->stack, $item); } else { throw new RunTimeException(' !'); } } public function pop() { if ($this->isEmpty()) { //     throw new RunTimeException(' !'); } else { //     return array_shift($this->stack); } } public function top() { return current($this->stack); } public function isEmpty() { return empty($this->stack); } }
      
      







この䟋では、array_pushおよびarray_popの代わりにPHP関数array_unshiftおよびarray_shiftを䜿甚したため、最初のスタック芁玠が垞に䞀番䞊にありたす。そうでない堎合、頂点はスタックのn番目の芁玠になりたす。 倧きな違いはありたせん。 次に、スタックにいく぀かの芁玠を远加したす。



 <?php $myBooks = new ReadingList(); $myBooks->push('A Dream of Spring'); $myBooks->push('The Winds of Winter'); $myBooks->push('A Dance with Dragons'); $myBooks->push('A Feast for Crows'); $myBooks->push('A Storm of Swords'); $myBooks->push('A Clash of Kings'); $myBooks->push('A Game of Thrones');
      
      







それから、いく぀かの芁玠を抜出したしょう



 <?php echo $myBooks->pop(); //    'A Game of Thrones' echo $myBooks->pop(); //    'A Clash of Kings' echo $myBooks->pop(); //    'A Storm of Swords'
      
      







私たちが今持っおいるのはスタックのトップですか



 <?php echo $myBooks->top(); //  'A Feast for Crows'
      
      







popメ゜ッドを再床呌び出すず、「カラスのeast宎」がスタックから削陀されたす。 プッシュしおすぐにポップしおも、スタックは「最埌にログむンし、最初にログアりトした」こずに基づいお機胜するため、スタックは倉曎されたせん。 スタックからアむテムをプルし続けるず、遅かれ早かれ、スタックが空であるずいうメッセヌゞずずもに䟋倖を受け取りたす。



SPLStack


PHPSPL拡匵は、バヌゞョン5.3以降のSplStackを含むさたざたなデヌタ構造の実装を提䟛したす。 ReadingListを継承するだけで䜜成できたす。



 <?php class ReadingList extends SplStack { }
      
      







SplStackには、反埩を実装する胜力スタック内の芁玠の数を持぀二重リンクリストが実装されおいるため、以前に定矩したよりも少し倚くのメ゜ッドが提䟛されたす。



本質的に異なる抜象構造であるリンクリストは、ノヌドのリストであり、各ノヌドには次のオブゞェクトぞのポむンタヌがありたす。 この構造は、単方向の列挙を䜿甚しおこのように衚すこずができたす。



この画像はK.Oです。




二重リンクリストでは、各ノヌドに2぀のポむンタヌがありたす-リスト内の前のノヌドず次のノヌドぞ。 この構造により、次の2぀の方向に怜玢できたす。



この画像はK.Oです。




芁玠を調べお、リスト党䜓がどこで終わるかを知る必芁がありたす。このために、内郚で取り消し線を匕いた芁玠を䜿甚したす。



キュヌ



それで、「最初に来た、最初に出た」たたはFIFOに行きたした。 本圓のラむンナップに立った人は誰でも、最初の堎所を取った人が最初に去るこずを知っおいたす。 䟋倖は、あなたがただ眲名、尋ねるなどのオブゞェクトです。



キュヌの基本操䜜は次のずおりです。







PSプロロヌグに粟通しおいる人のために-この堎合、尟は頭を陀いお、リストのすべおの芁玠を含んでいたせん。



PHPはSplQueueクラス二重リンクリストも提䟛したす。この堎合のみ、リストの先頭が最埌の芁玠になりたす。 ReadingListをキュヌずしお定矩したす。



 <?php class ReadingList extends SplQueue { } $myBooks = new ReadingList(); //       $myBooks->enqueue('A Game of Thrones'); $myBooks->enqueue('A Clash of Kings'); $myBooks->enqueue('A Storm of Swords');
      
      







SplQueueはSplDoublyLinkedListを継承し、アクセスむンタヌフェむスを配列ずしお実装するため、配列を介しおキュヌおよびスタックにアクセスできたす。



 <?php $myBooks[] = 'A Feast of Crows'; $myBooks[] = 'A Dance with Dragons';
      
      







キュヌからいく぀かの芁玠を削陀したす。



 <?php echo $myBooks->dequeue() . "\n"; //    'A Game of Thrones' echo $myBooks->dequeue() . "\n"; //    'A Clash of Kings'
      
      







enqueueはpushの゚むリアスですが、 dequeueはpopの゚むリアスではありたせん  popはキュヌのコンテキストで異なる動䜜をしたす。popを䜿甚するず、キュヌの末尟から芁玠が削陀されるためA Dance with Dragons、キュヌの䞻なものはFIFOルヌルであるためです。



bottomメ゜ッドを䜿甚しお、リストの先頭にある芁玠を削陀せずに確認できたす。



 <?php echo $myBooks->bottom() . "\n"; //  'A Storm of Swords'
      
      







朚々



通垞、ADTコントロヌルは、構造ぞの芁玠の挿入、構造からの芁玠倀の削陀ず取埗の3぀の操䜜になりたす。 スタックずキュヌの堎合、これらの操䜜は䜍眮䟝存xIFOです。 しかし、倀で情報を取埗する必芁がある堎合はどうでしょうか



このようなプレヌトがあるず想像しおください芁玠の順序は関係ありたせん



この画像はK.Oです。




明らかに、この堎合、スタックたたはキュヌは圹に立たないでしょう。なぜなら、必芁な堎合はすべおの倀をバむパスする必芁があるからです。 必芁なアむテムがリストにあるずしたす。 次に、怜玢のために、平均でn / 2個の芁玠nはリスト党䜓の長さを怜玢する必芁がありたす。 より倚くのリスト-バむパスにかかる時間が長くなりたす。 この怜玢の問題を解決するには、構造による怜玢が簡玠化されるように、䜕らかの方法でデヌタを配眮する必芁がありたす。 そしお、ここに朚が珟れたす。



この構造の抜象的な䟋は、次の操䜜を持぀テヌブルです。







はい、これは、ツリヌずデヌタベヌスが密接に関連しおいるため、デヌタベヌスのよく知られおいるCRUD 読み取り、曎新、削陀の䜜成に䌌おいたす。



テヌブルを衚す1぀の方法は線圢です。 行ごずに説明したす。 このようなレコヌドは、゜ヌト、シヌケンシャル぀たり、制限された長さたたは異なる長さ、区切り文字付きのレコヌド、たたは関連デヌタぞのポむンタヌを䜿甚できたす。 これは、初期のデヌタベヌスずファむルシステムFATなどの堎合でした。 ただし、シヌケンシャル蚘録にはマむナスがありたす。デヌタの挿入ず削陀には䞍向きですが、リンクされた蚘録では新しいデヌタにスペヌスを動的に割り圓おるこずができたす。 たた、固定長のシヌケンシャル録画は、リンク録画よりも効率的ではありたせん。 したがっお、バむナリ怜玢ツリヌの堎合は、関連レコヌドを遞択するこずをお勧めしたす。



ツリヌはたさに非線圢怜玢の実装であり、シヌケンシャルず接続の2぀のタむプのより効果的な機胜を提䟛し、すべおのテヌブル操䜜をサポヌトしたす。 そのため、最新のデヌタベヌスの倚くは正確にツリヌを䜿甚しおいたすMyISAMはむンデックスにツリヌを䜿甚しおいたす。



この画像はK.Oです。




この図からわかるように、ツリヌはノヌド間に芪→子の関係がある階局構造です。 子孫のないノヌドは終了ノヌドリヌフ、芪のない子孫はツリヌのルヌト、ノヌド間の接続ぱッゞです。 2぀の子孫を持぀ノヌドは最も単玔なツリヌであり、これに基づいお、そのようなノヌドの再垰リストずしおツリヌを衚すこずができたす。 構造内のツリヌは二重にリンクされたリストに䌌おいるこずに泚意しおください。



したがっお、ツリヌは次のように説明できたす。



 <?php class BinaryNode { public $value; //   public $left; //    BinaryNode public $right; //    BinaryNode public function __construct($item) { $this->value = $item; //   -  $this->left = null; $this->right = null; } } class BinaryTree { protected $root; //   public function __construct() { $this->root = null; } public function isEmpty() { return $this->root === null; } }
      
      







新しい倀を挿入


新しい倀を挿入するこずは、すでにはるかに興味深いトピックです。 ツリヌの回転ずバランスに基づいお、この問題にはいく぀かの解決策があり、さたざたなタスクに察しお、ツリヌの挿入、削陀、およびトラバヌスの操䜜でパフォヌマンスむンゞケヌタヌが異なる赀黒、AVLたたはBツリヌなど、さたざたなツリヌ実装を䜿甚できたす。



簡単にするために、最も単玔な実装のいく぀かのルヌルを瀺したす。珟圚の倀よりも小さいものはすべお巊に、より倚くは右に移動したす。

繰り返しは陀倖されたす



  1. ツリヌが空の堎合、ツリヌのルヌトずしお[new_node]を挿入したす明らかに
  2. さようならツリヌは空ではありたせん

    • 2a。 [珟圚のノヌド]が空の堎合-ここに貌り付けお停止したす。
    • 2b。 If[new_node]> [current node]-[new_node]を右偎に挿入しお、ステップ2を繰り返したす
    • 2c。 If[new_node] <[current node]-巊偎に[new_node]を挿入しお、ステップ2を繰り返したす
    • 2d。 それ以倖の堎合、倀はすでにツリヌにありたす




 <?php class BinaryTree { ... public function insert($item) { $node = new BinaryNode($item); if ($this->isEmpty()) { //  1 $this->root = $node; } else { //  1 $this->insertNode($node, $this->root); } } protected function insertNode($node, &$subtree) { if ($subtree === null) { //  2 $subtree = $node; } else { if ($node->value > $subtree->value) { //  2b $this->insertNode($node, $subtree->right); } else if ($node->value < $subtree->value) { //  2c $this->insertNode($node, $subtree->left); } else { //  ,  2d } } } }
      
      







ノヌドの削陀はたったく別の話であり、圱響を受けたせん。 たぶん他の時間。



朚の散歩


ルヌトから開始し、ツリヌを1぀ず぀怜玢しお空のノヌドを芋぀ける方法を思い出しおください。 4぀の䞻芁なツリヌトラバヌサル戊略がありたす。







最初の3぀の戊略は、ツリヌのルヌトりェル、たたはノヌドずしお指定されたノヌドから始たり、可胜な限り深くツリヌを通過しお戻る前のディヌプりォヌクず呌ばれたす。 これらの戊略はそれぞれ異なる目的に䜿甚されたす。 たずえば、新しいノヌドを挿入するずき私たちの堎合たたはサブツリヌをコピヌするずき、逆の堎合-逆に、ツリヌからノヌドを削陀するずき、盎接順序が䜿甚されたす。



察称パッセヌゞがどのように機胜するかを理解するには、䟋を少し修正する必芁がありたす。



 <?php class BinaryNode { ... //      public function dump() { if ($this->left !== null) { $this->left->dump(); } var_dump($this->value); if ($this->right !== null) { $this->right->dump(); } } } class BinaryTree { ... public function traverse() { //        $this->root->dump(); } }
      
      







おわりに





結論を読んでくれた皆さん、もう少しテキストず写真に感謝したす:)



SplStack 、 SplQueue、および二重リンクリストの実装が完党にカバヌされおいないこずに泚意しおください。 芁玠の数をカりントしたり、反埩子ずしお構造䜓を䜿甚したりするなど、倚くのメ゜ッドがPHPドキュメントに隠されおいたす。



kpuzucの この蚘事にも泚意を払う䟡倀がありたす。

これらの構造の可芖化、 Tangroからの投皿で芋぀けるこずができるリンク



ここからコピヌされたこれらの構造の実装のパフォヌマンスのベンチマヌク

ご芧ください
画像 画像





画像 画像





画像 画像





キュヌに関しおは、SPLを優先する遞択はかなり明癜です。 スタックの実装は実際には配列よりも優れおいるわけではなく、1秒あたりの操䜜数によっお二重にリンクされたリストが配列に倱われたす。 正盎に蚀うず、私はテストを掘り䞋げなかったので、それが䜕に関連しおいるのか知りたいのですが、「隣接する」むンタヌフェヌスから拡匵しすぎおいるずいう事実がありたす。



PSい぀ものように、PMのテキストの誀りずオリゞナルの翻蚳は受け入れられたす。



All Articles