樹(Tree)是n(n≥0)個結點的有限集,它或爲空樹(n = 0);或爲非空樹,對於非空樹T:
(1)有且僅有一個稱之爲根的結點;
(2)除根結點之外的其他結點可分爲m(m>0)個互不相交的有限集T1, T2, …, Tm, 其中每個集合自己又是一棵樹,而且稱爲根的子樹(SubTree)。
算法
二叉樹的定義
spa
二叉樹(Binary Tree)是n(n≥0)個結點所構成的集合,它或爲空樹(n = 0);或爲非空樹,對於非空樹T:
(1)有且僅有一個稱之爲根的結點;
(2)除根結點之外的其他結點分爲兩個互不相交的子集T1和T2,分別稱爲T的左子樹和右子樹,且T1和T2自己又都是二叉樹。
3d
爲什麼要重點研究每結點最多隻有兩個 「叉」 的樹?
二叉樹的結構最簡單,規律性最強;
能夠證實,全部樹都能轉爲惟一對應的二叉樹,不失通常性。指針
無code
CreateBiTree(&T,definition)
初始條件;definition給出二叉樹T的定義。
操做結果:按definition構造二叉樹T。blog
PreOrderTraverse(T)
初始條件:二叉樹T存在。
操做結果:先序遍歷T,對每一個結點訪問一次。
InOrderTraverse(T)
初始條件:二叉樹T存在。
操做結果:中序遍歷T,對每一個結點訪問一次。
PostOrderTraverse(T)
初始條件:二叉樹T存在。
操做結果:後序遍歷T,對每一個結點訪問一次。
排序
滿二叉樹是葉子一個也很多的樹,而徹底二叉樹雖然前n-1層是滿的,但最底層卻容許在右邊缺乏連續若干個結點。滿二叉樹是徹底二叉樹的一個特例。
遞歸
實現:按滿二叉樹的結點層次編號,依次存放二叉樹中的數據元素。
ci
typedef struct BiNode{ TElemType data; struct BiNode *lchild,*rchild; //左右孩子指針 }BiNode,*BiTree;
typedef struct TriTNode { TelemType data; struct TriTNode *lchild,*parent,*rchild; }TriTNode,*TriTree;
遍歷定義——指按某條搜索路線遍訪每一個結點且不重複(又稱周遊)。
遍歷用途——它是樹結構插入、刪除、修改、查找和排序運算的前提,是二叉樹一切運算的基礎和核心。 get
口訣:
DLR—先序遍歷,即先根再左再右
LDR—中序遍歷,即先左再根再右
LRD—後序遍歷,即先左再右再根
先序遍歷算法
Status PreOrderTraverse(BiTree T){ if(T==NULL) return OK; //空二叉樹 else{ cout<<T->data; //訪問根結點 PreOrderTraverse(T->lchild); //遞歸遍歷左子樹 PreOrderTraverse(T->rchild); //遞歸遍歷右子樹 } }
中序遍歷算法
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); //遞歸建立右子樹 } }
int NodeCount(BiTree T){ if(T == NULL ) return 0; else return NodeCount(T->lchild)+NodeCount(T->rchild)+1; }
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); }
二叉鏈表空間效率這麼低,可否利用這些空閒區存放有用的信息或線索?
——能夠用它來存放當前結點的直接前驅和後繼等線索,以加快查找速度。
先序線索二叉樹
中序線索二叉樹
後序線索二叉樹
樹的存儲結構--二叉鏈表表示法
typedef struct CSNode{ ElemType data; struct CSNode *firstchild,*nextsibling; }CSNode,*CSTree;
。。。。。