1. 程式人生 > 其它 >樹的基本概念與二叉樹相關

樹的基本概念與二叉樹相關

基本概念:(雙親,兄弟,堂兄弟等不在這裡贅述) 結點(node):包含一個數據元素及若干指向其子樹的分支 結點的度(degree):結點擁有子樹的個數 樹的度:樹中所有結點的度的最大值 葉子結點(leaf):度為0的結點 二叉樹的性質: 1.在二叉樹的第i層至多有2^(i-1)個結點 example 1 2 3 4 5 6 7 ** 第2層有2^1 ** 第3層有2^4 2.深度為k的二叉樹至多有2^k-1個結點 example: 如上二叉樹:深度為3 總共2^3-1=7個node 3.對於任意一個二叉樹T,若終端結點為n0,度為2的結點數為n2,n0=n2+1;
example: 如上二叉樹:終端結點4,度數為2的結點n2=3
**完全二叉樹: 1.所有葉子結點只能出現在層號最大的兩層上; 2.對任意節點,若其右子樹的層高為k,左子樹必為k或k+1;
4.具有n個結點的完全二叉樹的深度為[log2(n)]+1
5.對於具有n個結點的完全二叉樹,如果按照對滿二叉樹的方式進行順序編號,對於任意序號為i的結點有: 1)i=1; 結點i為root,無parent;i>1則parent=i/2 2) 2i<=n; 結點i的左孩子結點序號為2i否則無左孩子 3)2i+1<=n;結點i的右孩子結點序號為2i+1否則無右孩子



二叉樹的儲存: 1.對於滿二叉樹以及完全二叉樹的適合儲存(順序儲存結構) 由性質5我們可以將標號為i的左孩子下標為2i,右孩子下標為2i+1,雙親的結點下標為[i/2]; 二叉樹的儲存結構定義:
1     #define MAX 100
2     typedef struct{
3         int Sqsitree[MAX+1];      //0號單元不用
4         int nodemax;               //陣列中最後一個節點的下標
5     }Bitree;
2.適用於所有二叉樹的儲存(鏈式儲存結構) 我們可以如下定義: _________________ |Lchild | Data |Rchild| 描述如下:
typedef struct
node{ int data; struct node* Lchild; struct node* Rchild; }sitnode,*Sitree;
同樣當我們需要父母時也可以加上parent,組成三叉連結串列

二叉樹的遍歷: 1.遞迴實現: A、先序遍歷:root->left->right B、中序遍歷:left->root->right C、後序遍歷:right->left->root
void FreOrder(Bitree root)
{
    if(root)
    {
        Visit(root->data);
        FreOrder(root->Lchild);
        FreOrder(root->Rchild);
    }
}
//中序遍歷和後序遍歷只是修改順序
2.非遞迴實現 先序遍歷的實現: 1)訪問root,root入棧並進入其左子樹,進而訪問左子樹的root併入棧,在進入下一層左子樹,...直到為空 2)棧非空則從棧頂退出上一層的結點,並進入該節點的右子樹
 1 void PreOrder(Bitree root){
 2     Seqstack *s;
 3     Bitree p;
 4     InitStack(S);
 5     p=root;
 6     while(p!=NULL||!IsEmpty(s))
 7     {
 8         while(p!=NULL)
 9         {
10             Visit(p->data);
11             Push(S,p);
12             p=p->Lchild;
13         }
14         if(!IsEmpty(S)){
15             Pop(S,p);
16             p=p->Rchild;
17         }
18     }
19 }
中序遍歷只是調換了data的訪問位置
後序遍歷: 1.當前結點進棧,並進入其左子樹,重複至當前結點為空; 2.若棧非空,判斷棧頂結點P的右子樹是否為空,右子樹是否訪問過,是則退棧
 1 void PostOrder(Bitree root)
 2 {
 3     SeqStack *s;
 4     Sitree p,q;
 5     InitStack(s);
 6     p=root;
 7     q=NULL;
 8     while(p!=NULL||!IsEmpty(S))
 9     {
10         while(p!=NULL);
11         {
12             push(s,p);
13             p=p->Lchild;
14         }
15         if(!IsEmpty(s))
16         {
17             Top(s,&p);
18             if((p->Rchild==NULL)||(p->Rchild==q))
19             {
20                 Pop(s,p);
21                 Visit(P->data);
22                 q=p;
23                 p=NULL;
24             }
25             else
26                 p = p-> Rchild;
27         }
28     }
29 
30 }

//以上是我用一小時對二叉樹的複習,其中運用棧的地方,讀者可以自行定義變化。

上面僅是博主的自己複習的內容,如果有用,感謝支援,如有不足,請大佬指正!