數據結構(C語言版)-第5章 樹和二叉樹

image

5.1  樹和二叉樹的定義

樹(Tree)是n(n≥0)個結點的有限集,它或爲空樹(n = 0);或爲非空樹,對於非空樹T:
(1)有且僅有一個稱之爲根的結點;
(2)除根結點之外的其他結點可分爲m(m>0)個互不相交的有限集T1, T2, …, Tm, 其中每個集合自己又是一棵樹,而且稱爲根的子樹(SubTree)。
算法

image

image

image

 

image

image

image

二叉樹的定義
spa

二叉樹(Binary Tree)是n(n≥0)個結點所構成的集合,它或爲空樹(n = 0);或爲非空樹,對於非空樹T:
(1)有且僅有一個稱之爲根的結點;
(2)除根結點之外的其他結點分爲兩個互不相交的子集T1和T2,分別稱爲T的左子樹和右子樹,且T1和T2自己又都是二叉樹。
3d

爲什麼要重點研究每結點最多隻有兩個 「叉」 的樹?
二叉樹的結構最簡單,規律性最強;
能夠證實,全部樹都能轉爲惟一對應的二叉樹,不失通常性。指針

image

5.2  案例引入

code

5.3  樹和二叉樹的抽象數據類型定義

CreateBiTree(&T,definition)
      初始條件;definition給出二叉樹T的定義。
      操做結果:按definition構造二叉樹T。blog

PreOrderTraverse(T)
      初始條件:二叉樹T存在。
      操做結果:先序遍歷T,對每一個結點訪問一次。
InOrderTraverse(T)
      初始條件:二叉樹T存在。
      操做結果:中序遍歷T,對每一個結點訪問一次。
PostOrderTraverse(T)
      初始條件:二叉樹T存在。
      操做結果:後序遍歷T,對每一個結點訪問一次。
排序

5.4  二叉樹的性質和存儲結構

image

image

image

滿二叉樹是葉子一個也很多的樹,而徹底二叉樹雖然前n-1層是滿的,但最底層卻容許在右邊缺乏連續若干個結點。滿二叉樹是徹底二叉樹的一個特例。
遞歸

image

image

二叉樹的順序存儲

實現:按滿二叉樹的結點層次編號,依次存放二叉樹中的數據元素。
ci

image

二叉樹的鏈式存儲

image

typedef struct BiNode{ TElemType data; struct  BiNode   *lchild,*rchild; //左右孩子指針
}BiNode,*BiTree;

image
image

typedef struct TriTNode { TelemType data; struct TriTNode *lchild,*parent,*rchild; }TriTNode,*TriTree;

5.5  遍歷二叉樹和線索二叉樹

遍歷定義——指按某條搜索路線遍訪每一個結點且不重複(又稱周遊)。
遍歷用途——它是樹結構插入、刪除、修改、查找和排序運算的前提,是二叉樹一切運算的基礎和核心。 get

遍歷規則

image

口訣:
DLR—先序遍歷,即先根再左再右
LDR—中序遍歷,即先左再根再右
LRD—後序遍歷,即先左再右再根

先序遍歷算法

Status PreOrderTraverse(BiTree T){ if(T==NULL) return OK; //空二叉樹
  else{ cout<<T->data; //訪問根結點
     PreOrderTraverse(T->lchild); //遞歸遍歷左子樹
     PreOrderTraverse(T->rchild); //遞歸遍歷右子樹
 } }

image

中序遍歷算法

Status InOrderTraverse(BiTree T){ if(T==NULL) return OK; //空二叉樹
  else{ InOrderTraverse(T->lchild); //遞歸遍歷左子樹
  cout<<T->data; //訪問根結點
     InOrderTraverse(T->rchild); //遞歸遍歷右子樹
 } }

後序遍歷算法

Status PostOrderTraverse(BiTree T){ if(T==NULL) return OK; //空二叉樹
  else{ PostOrderTraverse(T->lchild); //遞歸遍歷左子樹
     PostOrderTraverse(T->rchild); //遞歸遍歷右子樹
     cout<<T->data; //訪問根結點
 } }

時間效率:O(n) //每一個結點只訪問一次
空間效率:O(n) //棧佔用的最大輔助空間

二叉樹的創建

void CreateBiTree(BiTree &T){ cin>>ch; if (ch==’#’)   T=NULL;      //遞歸結束,建空樹
else{ T=new BiTNode;    T->data=ch;                                      //生成根結點
    CreateBiTree(T->lchild);  //遞歸建立左子樹
    CreateBiTree(T->rchild); //遞歸建立右子樹
 } }

二叉樹遍歷算法的應用

image

int NodeCount(BiTree T){ if(T == NULL ) return 0; else return NodeCount(T->lchild)+NodeCount(T->rchild)+1; }

image

int LeadCount(BiTree T){ if(T==NULL)     //若是是空樹返回0
        return 0; if (T->lchild == NULL && T->rchild == NULL) return 1; //若是是葉子結點返回1
    else return LeadCount(T->lchild) + LeadCount(T->rchild); }

image

二叉鏈表空間效率這麼低,可否利用這些空閒區存放有用的信息或線索?
——能夠用它來存放當前結點的直接前驅和後繼等線索,以加快查找速度。

線索化二叉樹

image

先序線索二叉樹

image

中序線索二叉樹

image

後序線索二叉樹

image

5.6  樹和森林

樹的存儲結構--二叉鏈表表示法

typedef struct CSNode{ ElemType data; struct CSNode     *firstchild,*nextsibling; }CSNode,*CSTree;
樹和森林的轉換。。。

image

image

image

image

image

5.7  哈夫曼樹及其應用

image

image

image

image

image

。。。。。

image

相關文章
相關標籤/搜索