php數據結構課程---五、樹(樹的 存儲方式 有哪些)
1、總結
一句話總結:
雙親表示法:data parent:$tree[1] = ["B",0];
孩子表示法:data firstChild:firstChild把他的全部兄弟都用鏈表存起來
雙親孩子表示法:比孩子表示法,多一個父親指針。
孩子兄弟表示法:data,存儲數據,firstchild第一個孩子節點,rightsib右兄弟節點
一、樹的度 是什麼意思?
樹內各結點的度的 最大值
二、樹的 存儲方式 中的 雙親表示法 的 代碼如何實現,及這種存儲方式的 優缺點?
data parent:$tree[1] = ["B",0];
優缺點:便於找到雙親,若是找到孩子則須要遍歷全部節點。
<?php //雙親表示法 // // A // / \ // B C // / / \ // D E F // /|\ \ // G H I J // $tree = []; $tree[0] = ["A",-1]; $tree[1] = ["B",0]; $tree[2] = ["C",0]; $tree[3] = ["D",1]; $tree[4] = ["E",2]; $tree[5] = ["F",2]; $tree[6] = ["G",3]; $tree[7] = ["H",3]; $tree[6] = ["I",3]; $tree[8] = ["J",4]; echo "<pre>"; var_dump($tree); //雙親表示法.便於找到雙親節點(即父節點)缺點不便於尋找孩子,尋找孩子須要遍歷整棵樹。
三、樹的 存儲方式 中的 孩子表示法 的 代碼如何實現,及這種存儲方式的 優缺點?
data firstChild:firstChild把他的全部兄弟都用鏈表存起來
$trees[4] = new CTBox("D",new CTNode(0,new CTNode(1,new CTNode(2))));
優缺點:便於查詢孩子和兄弟節點,可是查詢雙親節點時,顯得不方便
節點:index 存儲鏈表/數組 索引下標;next 指向下個兄弟 CTNode 節點;
樹:$data 存儲節點數據;$firstChild 存儲第一個孩子節點 類型爲CTNodephp
<?php //孩子表示法 //節點, // index 存儲鏈表/數組 索引下標 // next 指向下個兄弟 CTNode 節點 class CTNode{ public $index; //經過索引獲取數據值 public $next; public function __construct($index,$ns = null){ $this->index = $index; $this->next = $ns; } } // $data 存儲節點數據 // $firstChild 存儲第一個孩子節點 類型爲CTNode class CTBox{ public $data; // public $parent; public $firstChild; public function __construct($data,$firstChild = null){ $this->data = $data; $this->firstChild = $firstChild; } } // // A // / \ // B C // / / \ // D E F // /|\ \ // G H I J // //使用數組存儲整棵樹 $trees = []; $trees[0] = new CTBox("G"); $trees[1] = new CTBox("H"); $trees[2] = new CTBox("I"); $trees[3] = new CTBox("J"); // 第一個孩子下標 兄弟下標 兄弟下標 $trees[4] = new CTBox("D",new CTNode(0,new CTNode(1,new CTNode(2)))); // 第一個孩子下標 $trees[5] = new CTBox("E",new CTNode(3)); $trees[6] = new CTBox("F"); // 第一個孩子下標 $trees[7] = new CTBox("B",new CTNode(4)); // 第一個孩子下標 兄弟下標 兄弟下標 $trees[8] = new CTBox("C",new CTNode(5,new CTNode(6))); $trees[9] = new CTBox("A",new CTNode(7,new CTNode(8))); //找到樹D節點,以及D的子樹 echo "<pre>"; echo "節點爲".$trees[4]->data."的子節點以下:"; echo "<br>"; $index = $trees[4]->firstChild->index; echo $trees[$index]->data; echo "<br>"; $index = $trees[4]->firstChild->next->index; echo $trees[$index]->data; echo "<br>"; $index = $trees[4]->firstChild->next->next->index; echo $trees[$index]->data;
四、樹的 存儲方式 中的 雙親孩子表示法 的 代碼如何實現,及這種存儲方式的 優缺點?
比孩子表示法,多一個父親指針:
五、樹的 存儲方式 中的 孩子兄弟表示法 的 代碼如何實現,及這種存儲方式的 優缺點?
data,存儲數據,firstchild第一個孩子節點,rightsib右兄弟節點:$trees[5] = new CSNode("E",$trees[0],$trees[4]);
<?php // 孩子兄弟表示法 class CSNode{ public $data; public $child; public $rightsb; public function __construct($d,$c,$r){ $this->data = $d; $this->child = $c; $this->rightsb = $r; } } // // A // / \ // B C // / / \ // D E F // /|\ \ // G H I J // $trees = []; $trees[0] = new CSNode("J"); $trees[1] = new CSNode("I"); $trees[2] = new CSNode("H",null,$trees[1]); $trees[3] = new CSNode("G",null,$trees[2]); $trees[4] = new CSNode("F"); $trees[5] = new CSNode("E",$trees[0],$trees[4]); $trees[6] = new CSNode("D",$trees[3]); $trees[7] = new CSNode("C",$trees[5]); $trees[8] = new CSNode("B",$trees[6],$trees[7]); $trees[9] = new CSNode("A",$trees[8]);
六、樹的遍歷方式有哪些?
先根遍歷:若樹非空,則先訪問根結點,再按照從左到右的順序遍歷根結點的每一棵子樹。
後根遍歷:若樹非空,則按照從左到右的順序遍歷根結點的每一棵子樹,以後再訪問根結點。
七、樹有哪些常見的類型?
決策樹:好比象棋開局,每一個象有兩種走法,每一個車有兩種走法,等等,因此象棋開局有42種走法(各個棋子走法之和),這就是決策樹
二叉樹:每一個結點最多有兩個子樹的樹結構
平衡二叉樹:它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,而且左右兩個子樹都是一棵平衡二叉樹
八、決策樹是什麼?
決策狀況:好比象棋開局,每一個象有兩種走法,每一個車有兩種走法,等等,因此象棋開局有42種走法(各個棋子走法之和),這就是決策樹
九、二叉搜索樹/二叉排序樹 是什麼?
若左子樹不空,則左子樹上全部結點的值均小於或等於它的根結點的值;
若右子樹不空,則右子樹上全部結點的值均大於或等於它的根結點的值;
左、右子樹也分別爲二叉排序樹;
十、二叉搜索樹/二叉排序樹 如何查找節點?
當前節點比要找的值小就去右子樹,否者去左子樹
十一、二叉樹的 遍歷方式 有哪些?
先序遍歷(DLR) 根左右 preOrder
中序遍歷(LDR) 左根右 inOrder
後序遍歷(LRD) 左右根 postOrder
<?php // // 8 // / \ // 3 10 // / \ \ // 1 6 14 // / \ / // 4 7 13 // class tree{ public $data; public $left = null ; public $right = null; public function __construct($data){ $this->data = $data; } // DLR public function preOrder(){ echo $this->data." "; if($this->left) $this->left->preOrder(); if($this->right) $this->right->preOrder(); } // LDR public function inOrder(){ if($this->left) $this->left->inOrder(); echo $this->data." "; if($this->right) $this->right->inOrder(); } // LRD public function postOrder(){ if($this->left) $this->left->postOrder(); if($this->right) $this->right->postOrder(); echo $this->data." "; } } $trees = new tree(8); $trees->left = new tree(3); $trees->left->left = new tree(1); $trees->left->right = new tree(6); $trees->left->right->left = new tree(4); $trees->left->right->right = new tree(7); $trees->right = new tree(10); $trees->right->right = new tree(14); $trees->right->right->left = new tree(13); echo "<pre>"; $trees->preOrder(); echo "<br>"; $trees->inOrder(); echo "<br>"; $trees->postOrder(); echo "<br>";
十二、二叉樹代碼如何實現?
$data,$left,$right
class tree{ public $data; public $left; public $right; public function preOrder(){ } public function inOrder(){ } Public function postOrder(){} }
1三、樹,森林,二叉樹之間的如何轉換 ?
任何一棵樹均可以按照必定的算法轉換成二叉樹。
任何森林均可以按照必定的算法轉換成樹,或者二叉樹。
擁有了二叉樹,調整成平衡二叉搜索樹,咱們即擁有了o(log2n)的查詢效率。
1四、樹如何轉換爲二叉樹?
(1)加線。就是在全部兄弟結點之間加一條連線;
(2)抹線。就是對樹中的每一個結點,只保留他與第一個孩子結點之間的連線,刪除它與其它孩子結點之間的連線;
(3)旋轉。就是以樹的根結點爲軸心,將整棵樹順時針旋轉必定角度,使之結構井井有條。
1五、森林如何轉換爲二叉樹?
(1)先把每棵樹轉換爲二叉樹;
(2)變爲右孩子節點:第一棵二叉樹不動,從第二棵二叉樹開始,依次把後一棵二叉樹的根結點做爲前一棵二叉樹的根結點的右孩子結點,用線鏈接起來。當全部的二叉樹鏈接起來後獲得的二叉樹就是由森林轉換獲得的二叉樹。