參考自: http://www.sitepoint.com/data-structures-2/ (PublishedJuly 5, 2013) php
第二篇開始搬到OSC上面來 node
數據結構管理常常遇到三種類型的操做: 數據庫
- 插入, 即向結構中插入數據
- 刪除, 即從結構中刪除數據
- 查詢, 即從結構中查詢數據 數據結構
好比說有這麼一張表: 數據庫設計
何歡 | 13911111111 |
吳佳旻 | 13922222222 |
徐琦怡 | 13933333333 |
咱們能夠把一張表抽象成四種類型的操做(這跟數據庫的crud操做很是相似): post
- 新建, 即新建一張表
- 插入, 即向表中插入數據
- 刪除, 即從表中刪除數據
- 查詢, 即從表中查詢數據 優化
這種表叫作線性植入,早期的數據庫設計)IBM’s Indexed Sequential Access Method (ISAM),MS-DOS’s File Allocation Table (FAT)等)等採用的就是這種方式。其缺點是插入和刪除的時候消耗比較大,由於值的長度是可大可小的。 this
而Tree的設計避免了這個問題(Why?),許多數據庫(如MySQL的MYISAM,Apple's HFS+, Microsoft’s NTFS, and btrfs for Linux等)都用Tree數據結構來構建索引。 spa
把它們變成PHP代碼: 設計
class BinaryNode { public $value; // contains the node item public $left; // the left child BinaryNode public $right; // the right child BinaryNode public function __construct($item) { $this->value = $item; // new nodes are leaf nodes $this->left = null; $this->right = null; } } class BinaryTree { protected $root; // the root node of our tree public function __construct() { $this->root = null; } public function isEmpty() { return $this->root === null; } }插入節點的邏輯
1 若是Tree是空的,就在root節點插入一個新節點
2 只要Tree不爲空:
a 若是當前節點是空的,就在這裏插入新節點,停止
b 不然,若是新節點 > 當前節點,就嘗試插入新節點到該節點的右側,而後重複步驟2
c 不然,若是新節點 < 當前節點,就嘗試插入新節點到該節點的左側,而後重複步驟2
d 不然,就說明值已經在Tree裏存在了,插不插都同樣,因此不插
插入節點的代碼
class BinaryTree { ... public function insert($item) { $node = new BinaryNode($item); if ($this->isEmpty()) { // special case if tree is empty $this->root = $node; } else { // insert the node somewhere in the tree starting at the root $this->insertNode($node, $this->root); } } protected function insertNode($node, &$subtree) { if ($subtree === null) { // insert node here if subtree is empty $subtree = $node; } else { if ($node->value > $subtree->value) { // keep trying to insert right $this->insertNode($node, $subtree->right); } else if ($node->value < $subtree->value) { // keep trying to insert left $this->insertNode($node, $subtree->left); } else { // reject duplicates } } } }
查詢樹的四種策略
- pre-order,即先查詢當前節點,而後查詢左右子節點 (比較適合於節點的插入 和 子樹克隆)
- in-order,即先查詢左節點,再查當前節點,再查右節點 (比較適合於搜索二叉樹)
- post-order,即先查詢左右節點,再查詢中節點 (比較適合於刪除節點)
- level-order,即先查詢當前節點,再查詢所有的相鄰節點,最後查詢下一級節點
下面的代碼演示了用 in-order 方式查詢:
class BinaryNode { ... // perform an in-order traversal of the current node 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() { // dump the tree rooted at "root" $this->root->dump(); } }
調用 traverse() 方法會顯示從root節點開始的按順序排序的整個Tree。
最後,這tmd有啥用? 誰能告訴我一下?
EOF