二叉樹原理和作用,總結


二叉樹

二叉樹是一種重要的數據結構,與數組、向量、鏈表都是一種順序容器,它們提供了按位置訪問數據的手段。但是有一個缺點,它們都是按照位置來確定數據,想要通過值來獲取數據,只能通過遍歷的方式。而二叉樹在很大程度上解決了這個缺點,二叉樹是按值來保存元素,也按值來訪問元素。

二叉樹由一個個節點組成,一個節點最多只能有兩個子節點,從根節點開始左右擴散,分左子節點和右子節點,向下一直分支。

許多實際問題抽象出來的數據結構往往是二叉樹的形式,即使是一般的樹也能簡單地轉換為二叉樹,而且二叉樹的存儲結構及其算法都較為簡單,因此二叉樹顯得特別重要。二叉樹是遞歸定義的。

(1)完全二叉樹—— 若設二叉樹的高度為h,除第 h 層外,其它各層 (1~h-1) 的結點數都達到最大個數,第h層有葉子節點,並且葉子結點都是從左到右依次排布,這就是完全二叉樹。

 

 
(2)滿二叉樹—— 除了葉結點外每一個結點都有左右子葉且葉子結點都處在最底層的二叉樹。

 

 
(3)平衡二叉樹—— 平衡二叉樹又被稱為AVL樹(區別於AVL算法),它是一棵二叉排序樹,且具有以下性質:它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。

 

 

二叉樹的基本性質

(1) 在非空二叉樹中,第i層的結點總數不超過  , i>=1;

(2) 深度為h的二叉樹最多有 個結點(h>=1),最少有h個結點;

(3) 對於任意一棵二叉樹,如果其葉結點數為N0,而度數為2的結點總數為N2,則N0=N2+1;
(4) 具有n個結點的完全二叉樹的深度為
(5)有N個結點的完全二叉樹各結點如果用順序方式存儲,則結點之間有如下關系:
           若I為結點編號則 如果I>1,則其父結點的編號為I/2;
           如果2*I<=N,則其左兒子(即左子樹的根結點)的編號為2*I;若2*I>N,則無左兒子;
           如果2*I+1<=N,則其右兒子的結點編號為2*I+1;若2*I+1>N,則無右兒子。
(6)給定N個節點,能構成h(N)種不同的二叉樹。
           h(N)為卡特蘭數的第N項。h(n)=C(2*n,n)/(n+1)。
(7)設有i個枝點,I為所有枝點的道路長度總和,J為葉的道路長度總和J=I+2i

 

 

 

二叉樹的遍歷

對於二叉樹來講最主要、最基本的運算是遍歷。 

從二叉樹的遞歸定義可知,一棵非空的二叉樹由根結點及左、右子樹這三個基本部分組成。因此,在任一給定結點上,可以按某種次序執行三個操作: 
 (1)訪問結點本身(N), 
 (2)遍歷該結點的左子樹(L), 
 (3)遍歷該結點的右子樹(R)。 

遍歷方法普遍有以下幾種:

先序遍歷(NLR)、中序遍歷(LNR),后序遍歷(LRN)和層次遍歷。

遍歷節點順序:

        先序遍歷(NLR):根、左子樹、右子樹

   中序遍歷(LNR):左子樹、根、右子樹

   后序遍歷(LRN):左子樹、右子樹、根

   層次遍歷:按照從上到下、從左到右的次序進行遍歷

 

二叉樹的代碼的實現

 

 

 1 <?php
 2 class Node{
 3     public $value;
 4     public $left;
 5     public $right;
 6 }
 7 //先序遍歷 根節點 ---> 左子樹 ---> 右子樹
 8 function preorder($root){
 9     $stack=array();
10     array_push($stack,$root);
11     while(!empty($stack)){
12         $center_node=array_pop($stack);
13         echo $center_node->value.' ';//先輸出根節點
14         if($center_node->right!=null){
15             array_push($stack,$center_node->right);//壓入左子樹
16         }
17         if($center_node->left!=null){
18             array_push($stack,$center_node->left);
19         }
20     }
21 }
22 //中序遍歷,左子樹---> 根節點 ---> 右子樹
23 function inorder($root){
24     $stack = array();
25     $center_node = $root;
26     while (!empty($stack) || $center_node != null) {
27              while ($center_node != null) {
28                  array_push($stack, $center_node);
29                  $center_node = $center_node->left;
30              }
31  
32              $center_node = array_pop($stack);
33              echo $center_node->value . " ";
34  
35              $center_node = $center_node->right;
36          }
37 }
38 //后序遍歷,左子樹 ---> 右子樹 ---> 根節點
39 function tailorder($root){
40     $stack=array();
41     $outstack=array();
42     array_push($stack,$root);
43     while(!empty($stack)){
44         $center_node=array_pop($stack);
45         array_push($outstack,$center_node);//最先壓入根節點,最后輸出
46         if($center_node->left!=null){
47             array_push($stack,$center_node->left);
48         }
49         if($center_node->right!=null){
50             array_push($stack,$center_node->right);
51         }
52     }
53     
54     while(!empty($outstack)){
55         $center_node=array_pop($outstack);
56         echo $center_node->value.' ';
57     }
58     
59 }
60 $a=new Node();
61 $b=new Node();
62 $c=new Node();
63 $d=new Node();
64 $e=new Node();
65 $f=new Node();
66 $a->value='A';
67 $b->value='B';
68 $c->value='C';
69 $d->value='D';
70 $e->value='E';
71 $f->value='F';
72 $a->left=$b;
73 $a->right=$c;
74 $b->left=$d;
75 $c->left=$e;
76 $c->right=$f;
77 preorder($a);//A B D C E F 
78 echo '<hr/>';
79 inorder($a);//D B A E C F
80 echo '<hr/>';
81 tailorder($a);//D B E F C A

 

 

 

二叉樹的用途

(有待更新)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM