1、二叉樹的定義及相關知識點php
1.定義:再計算機科學中,二叉樹是每一個結點最多有兩個子樹的樹結構,且二叉樹的子樹有左右之分,順序不能任意顛倒;node
2.性質:數據結構
a.若是二叉樹的根節點層次從0開始,那麼第i層樹的節點爲 2i 個節點;學習
b.高度爲k的一個二叉樹,那麼它的結點node至多有2k-1個結點(k>=1,這裏注意了有些博客以及維基百科中是k>=0,從0開始的,因此高度爲K的二叉樹節點之多爲2(k+1)-1個結點);this
c.對任何一棵二叉樹,若是其葉子結點(度爲0)數爲m, 度爲2的結點數爲n, 則m = n + 1(這一條不太理解,待學習)。spa
3.完美二叉樹(滿二叉樹):深度爲K(K>=1)的一個二叉樹,其結點有2k-1個結點,則該二叉樹爲完美二叉樹;code
4.徹底二叉樹:從根結點到倒數第二層,知足完美二叉樹(滿二叉樹),最後一層能夠不徹底填充,可是必須按照從左到右的順序,其葉子結點都靠左對齊;對象
5.完滿二叉樹blog
未完待續......博客
2、二叉樹的遍歷
<?php class Node{ public $value = Null; public $child_left = Null; public $child_right = Null; function __construct($value) { if(!is_null($value) || !empty($value)) $this->value = $value; } /*** * 建立$this->>value的左右子樹節點 * @param $left * @param $right * */ public function createNodeLrChild(Node $left=Null, Node $right=Null) { if(is_null($this->value) || empty($this->value)) return false; if(!is_null($left) && !empty($left)) $this->child_left = $left; if(!is_null($right) && !empty($right)) $this->child_right = $right; } } final class Ergodic{ /*** * 先序遍歷:先從根節點、再左子樹、再右子樹;在遍歷左右子樹的時候,仍然須要先從根節點開始遍歷,再遍歷左子樹,再遍歷右子樹 * @param $root */ public static function preOrder($root) { # 定義一個棧 $stack = array(); array_push($stack, $root); # 循環取出節點的左右子樹並壓入棧中,再取出 while(!empty($stack)) { // 彈出一個節點,並輸出節點的值 $center_order = array_pop($stack); echo $center_order->value.' '; // 取出左右子樹節點,並壓去棧中(注意順序:先序遍歷是根節點、左子樹、右子樹;因此應該先壓入右子樹節點,先進後出) if(!empty($center_order->child_right) && !is_null($center_order->child_right)) array_push($stack, $center_order->child_right); if(!empty($center_order->child_left) && !is_null($center_order->child_left)) array_push($stack, $center_order->child_left); } } /*** * 中序遍歷:先左子樹、再根節點、再右子樹; * @param $root */ public static function midOrder($root) { $stack = array(); $center_order = $root; while(!empty($stack) || !empty($center_order) || $center_order !=null) { while($center_order !=null) { var_dump($center_order); // 輸出該信息,有助於理解遍歷的過程 array_push($stack, $center_order); $center_order = $center_order->child_left; // 一直查找節點的左子樹節點(是否有值,若是沒有,則退出循環) } $center_order = array_pop($stack); // 而後彈出該節點的對象,獲取該節點的值 echo $center_order->value.' ';// 輸出該值 $center_order = $center_order->child_right; // 而後再獲取該節點的右子樹的值(看看是否存在左子樹等) } } /*** * 後序遍歷 * @param $roots */ public static function endOrder($root) { $stack = array(); $visit_stack = array(); array_push($stack, $root); while(!empty($stack)) { $center_order = array_pop($stack); array_push($visit_stack, $center_order); if($center_order->child_left != null) array_push($stack, $center_order->child_left); if($center_order->child_right != null) array_push($stack, $center_order->child_right); } while(!empty($visit_stack)) { $center_order = array_pop($visit_stack); echo $center_order->value.' '; } } } # 建立二叉樹數據結構 $a = new Node('A'); $b = new Node('B'); $c = new Node('C'); $d = new Node('D'); $e = new Node('E'); $f = new Node('F'); $g = new Node('G'); $h = new Node('H'); $i = new Node('I'); # 添加節點的左右子節點 $a->createNodeLrChild($b, $c); $b->createNodeLrChild($d, $g); $c->createNodeLrChild($e, $f); $d->createNodeLrChild($h, $i); # 先序遍歷 //Ergodic::preOrder($a); //echo "\n"; //Ergodic::midOrder($a); //echo "\n"; //Ergodic::endOrder($a);