數(shù)據(jù)結構二叉樹教學課件_第1頁
數(shù)據(jù)結構二叉樹教學課件_第2頁
數(shù)據(jù)結構二叉樹教學課件_第3頁
數(shù)據(jù)結構二叉樹教學課件_第4頁
數(shù)據(jù)結構二叉樹教學課件_第5頁
已閱讀5頁,還剩146頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、數(shù)據(jù)結構二叉樹教學數(shù)據(jù)結構二叉樹教學6.1 樹的類型定義樹的類型定義6.2 6.2 二叉樹的類型定義二叉樹的類型定義6.3 二叉樹的存儲結構二叉樹的存儲結構6.4 二叉樹的遍歷二叉樹的遍歷6.5 線索二叉樹線索二叉樹6.6 樹和森林的表示方法樹和森林的表示方法6.7 樹和森林的遍歷樹和森林的遍歷6.8 哈夫曼樹與哈夫曼編碼哈夫曼樹與哈夫曼編碼數(shù)據(jù)結構二叉樹教學6.1 樹的類型定義樹的類型定義數(shù)據(jù)結構二叉樹教學數(shù)據(jù)對象數(shù)據(jù)對象 D:D是具有相同特性的數(shù)據(jù)元素的集合。是具有相同特性的數(shù)據(jù)元素的集合。 若若D為空集,則稱為空樹;為空集,則稱為空樹; 否則否則: (1) 在在D中存在唯一的稱為根的數(shù)據(jù)

2、元素中存在唯一的稱為根的數(shù)據(jù)元素root, (2) 當當n1時,其余結點可分為時,其余結點可分為m (m0)個互個互 不相交的有限集不相交的有限集T1, T2, , Tm, 其中每一其中每一 棵子集本身又是一棵符合本定義的樹,棵子集本身又是一棵符合本定義的樹, 稱為根稱為根root的子樹。的子樹。 數(shù)據(jù)關系數(shù)據(jù)關系 R:數(shù)據(jù)結構二叉樹教學 基本操作:基本操作:查查 找找 類類 插插 入入 類類刪刪 除除 類類數(shù)據(jù)結構二叉樹教學 Root(T) / 求樹的根結點求樹的根結點 查找類:查找類:Value(T, cur_e) / 求當前結點的元素值求當前結點的元素值 Parent(T, cur_e)

3、 / 求當前結點的雙親結點求當前結點的雙親結點LeftChild(T, cur_e) / 求當前結點的最左孩子求當前結點的最左孩子 RightSibling(T, cur_e) / 求當前結點的右兄弟求當前結點的右兄弟TreeEmpty(T) / 判定樹是否為空樹判定樹是否為空樹 TreeDepth(T) / 求樹的深度求樹的深度TraverseTree( T, Visit() ) / 遍歷遍歷數(shù)據(jù)結構二叉樹教學InitTree(&T) / 初始化置空樹初始化置空樹 插入類:插入類:CreateTree(&T, definition) / 按定義構造樹按定義構造樹Assign(

4、T, cur_e, value) / 給當前結點賦值給當前結點賦值InsertChild(&T, &p, i, c) / 將以將以c為根的樹插入為結點為根的樹插入為結點p的第的第i棵子樹棵子樹數(shù)據(jù)結構二叉樹教學 ClearTree(&T) / 將樹清空將樹清空 刪除類:刪除類:DestroyTree(&T) / 銷毀樹的結構銷毀樹的結構DeleteChild(&T, &p, i) / 刪除結點刪除結點p的第的第i棵子樹棵子樹數(shù)據(jù)結構二叉樹教學ABCDEFGHIJMKLA( )T1T3T2樹根例如例如: :B(E, F(K, L), C(G), D

5、(H, I, J(M)數(shù)據(jù)結構二叉樹教學() 有確定的根;() 樹根和子樹根之間為有向關系。有向樹:有向樹:有序樹:有序樹:子樹之間存在確定的次序關系。無序樹:無序樹:子樹之間不存在確定的次序關系。數(shù)據(jù)結構二叉樹教學基基 本本 術術 語語數(shù)據(jù)結構二叉樹教學結點結點: :結點的度結點的度: :樹的度樹的度: :葉子結點葉子結點: :分支結點分支結點: :數(shù)據(jù)元素+ +若干指向子樹的分支分支的個數(shù)樹中所有結點的度的最大值度為零的結點度大于零的結點DHIJM數(shù)據(jù)結構二叉樹教學(從根到結點的)路徑路徑:孩子孩子結點、雙親雙親結點、兄弟兄弟結點、堂兄弟祖先祖先結點、子孫子孫結點結點的層次結點的層次: :

6、樹的深度:樹的深度: 由從根根到該結點所經分支和結點構成ABCDEFGHIJMKL假設根結點的層次為1,第l 層的結點的子樹根結點的層次為l+1樹中葉子結點所在的最大層次數(shù)據(jù)結構二叉樹教學任何一棵非空樹是一個二元組 Tree = (root,F(xiàn))其中:其中:root 被稱為根結點, F 被稱為子樹森林森林:森林:是 m(m0)棵互不相交的樹的集合ArootBEFKLCGDHIJMF數(shù)據(jù)結構二叉樹教學對比對比樹型結構樹型結構和和線性結構線性結構的結構特點的結構特點數(shù)據(jù)結構二叉樹教學線性結構線性結構樹型結構樹型結構第一個數(shù)據(jù)元素第一個數(shù)據(jù)元素 ( (無前驅無前驅) ) 根結點根結點 ( (無前驅無

7、前驅) )最后一個數(shù)據(jù)元素最后一個數(shù)據(jù)元素 (無后繼無后繼)多個葉子結點多個葉子結點 ( (無后繼無后繼) )其它數(shù)據(jù)元素其它數(shù)據(jù)元素( (一個前驅、一個前驅、 一個后繼一個后繼) )其它數(shù)據(jù)元素其它數(shù)據(jù)元素( (一個前驅、一個前驅、 多個后繼多個后繼) )數(shù)據(jù)結構二叉樹教學6.2 二叉樹的類型定義二叉樹的類型定義數(shù)據(jù)結構二叉樹教學 二叉樹或為空樹空樹;或是由一個根結根結點點加上兩棵兩棵分別稱為左子樹左子樹和右子樹的、互不交的互不交的二叉樹二叉樹組成。ABCDEFGHK根結點左子樹右子樹EF數(shù)據(jù)結構二叉樹教學二叉樹的五種基本形態(tài):二叉樹的五種基本形態(tài):N空樹空樹只含根結點只含根結點NNNLRR

8、右子樹為空樹右子樹為空樹L左子樹為空樹左子樹為空樹左右子左右子樹均不樹均不為空樹為空樹數(shù)據(jù)結構二叉樹教學 二叉樹的主要基本操作二叉樹的主要基本操作:查查 找找 類類插插 入入 類類刪刪 除除 類類數(shù)據(jù)結構二叉樹教學 Root(T); Value(T, e); Parent(T, e); LeftChild(T, e); RightChild(T, e); LeftSibling(T, e); RightSibling(T, e); BiTreeEmpty(T); BiTreeDepth(T); PreOrderTraverse(T, Visit(); InOrderTraverse(T, Vi

9、sit(); PostOrderTraverse(T, Visit(); LevelOrderTraverse(T, Visit();數(shù)據(jù)結構二叉樹教學 InitBiTree(&T); Assign(T, &e, value); CreateBiTree(&T, definition); InsertChild(T, p, LR, c);數(shù)據(jù)結構二叉樹教學ClearBiTree(&T); DestroyBiTree(&T);DeleteChild(T, p, LR);數(shù)據(jù)結構二叉樹教學二叉樹二叉樹的重要特性的重要特性數(shù)據(jù)結構二叉樹教學 性質性質 1 :

10、在二叉樹的第 i 層上至多有2i-1 個結點。 (i1)用歸納法用歸納法證明證明: 歸納基歸納基: 歸納假設:歸納假設: 歸納證明:歸納證明:i = 1 層時,只有一個根結點, 2i-1 = 20 = 1;假設對所有的 j,1 j i,命題成立;二叉樹上每個結點至多有兩棵子樹,則第 i 層的結點數(shù) = 2i-2 2 = 2i-1 。數(shù)據(jù)結構二叉樹教學 性質性質 2 : 深度為 k 的二叉樹上至多含 2k-1 個結點(k1)證明:證明: 基于上一條性質,深度為 k 的二叉樹上的結點數(shù)至多為 20+21+ +2k-1 = 2k-1 數(shù)據(jù)結構二叉樹教學 性質性質 3 : 對任何一棵二叉樹,若它含有n

11、0 個葉子結點、n2 個度為 2 的結點,則必存在關系式:n0 = n2+1證明:證明:設設 二叉樹上結點總數(shù) n = n0 + n1 + n2又又 二叉樹上分支總數(shù) b = n1 + 2n2而 b = n-1 = n0 + n1 + n2 - 1由此,由此, n0 = n2 + 1數(shù)據(jù)結構二叉樹教學兩類兩類特殊特殊的二叉樹:的二叉樹:滿二叉樹滿二叉樹:指的是深度為k且含有2k-1個結點的二叉樹。完全二叉樹完全二叉樹:樹中所含的 n 個結點和滿二叉樹中編號編號為為 1 至至 n 的結點的結點一一對應。123456789 10 11 12 13 14 15abcdefghij數(shù)據(jù)結構二叉樹教學

12、性質性質 4 : 具有 n 個結點的完全二叉樹的深度深度為 log2n +1證明:證明:設設 完全二叉樹的深度為 k 則根據(jù)第二條性質得 2k-1 n 2k 即 k-1 log2 n n,則該結點無左孩子, 否則,編號為 2i 的結點為其左孩子左孩子結點;(3) 若 2i+1n,則該結點無右孩子結點, 否則,編號為2i+1 的結點為其右孩子右孩子結點。數(shù)據(jù)結構二叉樹教學6.3 二叉樹的存儲結構二叉樹的存儲結構二、二叉樹的鏈式二、二叉樹的鏈式 存儲表示存儲表示一、一、 二叉樹的順序二叉樹的順序 存儲表示存儲表示數(shù)據(jù)結構二叉樹教學#define MAX_TREE_SIZE 100 / 二叉樹的最大

13、結點數(shù)typedef TElemType SqBiTreeMAX_TREE_SIZE; / 0號單元存儲根結點SqBiTree bt;一、一、 二叉樹的順序存儲表示二叉樹的順序存儲表示數(shù)據(jù)結構二叉樹教學例如例如: A B D C E F 0 1 2 3 4 5 6 7 8 9 10 11 12 13ABCDEF1401326數(shù)據(jù)結構二叉樹教學二、二叉樹的鏈式存儲表示二、二叉樹的鏈式存儲表示1. 1. 二叉鏈表二叉鏈表2三叉鏈表三叉鏈表3 3雙親鏈表雙親鏈表4線索鏈表線索鏈表數(shù)據(jù)結構二叉樹教學ADEBCF rootlchild data rchild結點結構結點結構:1. 1. 二叉鏈表二叉鏈表

14、數(shù)據(jù)結構二叉樹教學typedef struct BiTNode / 結點結構結點結構 TElemType data; struct BiTNode *lchild, *rchild; / 左右孩子指針 BiTNode, *BiTree;lchild data rchild結點結構結點結構:C 語言的類型描述如下語言的類型描述如下: :數(shù)據(jù)結構二叉樹教學rootADEBCF 2三叉鏈表三叉鏈表parent lchild data rchild結點結構結點結構:數(shù)據(jù)結構二叉樹教學 typedef struct TriTNode / 結點結構結點結構 TElemType data; struct T

15、riTNode *lchild, *rchild; / 左右孩子指針 struct TriTNode *parent; /雙親指針 TriTNode, *TriTree;parent lchild data rchild結點結構結點結構:C 語言的類型描述如下語言的類型描述如下: :數(shù)據(jù)結構二叉樹教學結點結構結點結構:3 3雙親鏈表雙親鏈表 data parentABDCEF0B41D42C03E14A-15F36LRTagLRRRL根根數(shù)據(jù)結構二叉樹教學 typedef struct BPTNode / 結點結構結點結構 TElemType data; int *parent; / 指向雙親

16、的指針 char LRTag; / 左、右孩子標志域 BPTNode typedef struct BPTree / 樹結構樹結構 BPTNode nodesMAX_TREE_SIZE; int num_node; / 結點數(shù)目 int root; / 根結點的位置 BPTree數(shù)據(jù)結構二叉樹教學6.4二叉樹的遍歷二叉樹的遍歷數(shù)據(jù)結構二叉樹教學一、問題的提出一、問題的提出二、先左后右的遍歷算法二、先左后右的遍歷算法三、算法的遞歸描述三、算法的遞歸描述四、中序遍歷算法的非遞歸描述四、中序遍歷算法的非遞歸描述四四、遍歷算法的應用舉例遍歷算法的應用舉例數(shù)據(jù)結構二叉樹教學 順著某一條搜索路徑巡訪巡訪二

17、叉樹中的結點,使得每個結點均被訪問一均被訪問一次次,而且僅被訪問一次僅被訪問一次。一、問題的提出一、問題的提出“訪問訪問”的含義可以很廣,如:輸出結點的信息等。數(shù)據(jù)結構二叉樹教學 “遍歷遍歷”是任何類型均有的操作,對線性結構而言,只有一條搜索路徑(因為每個結點均只有一個后繼),故不需要另加討論。而二叉樹是非線性結構, 每個結點有兩個后繼每個結點有兩個后繼,則存在如何遍歷存在如何遍歷即按什么樣的搜索搜索路徑路徑進行進行遍歷的問題。數(shù)據(jù)結構二叉樹教學 對對“二叉樹二叉樹”而言,可以有而言,可以有三條搜索路徑:三條搜索路徑: 1先上后下先上后下的按層次遍歷; 2先左先左(子樹)后右后右(子樹)的遍歷

18、; 3先右先右(子樹)后左后左(子樹)的遍歷。數(shù)據(jù)結構二叉樹教學二、先左后右的遍歷算法二、先左后右的遍歷算法先先(根)序的遍歷算法中中(根)序的遍歷算法后后(根)序的遍歷算法根根左子樹右子樹根根根根根根根根根根數(shù)據(jù)結構二叉樹教學 若二叉樹為空樹,則空操作;否則,(1)訪問根結點;(2)先序遍歷左子樹;(3)先序遍歷右子樹。先(根)序的遍歷算法:先(根)序的遍歷算法:數(shù)據(jù)結構二叉樹教學 若二叉樹為空樹,則空操作;否則,(1)中序遍歷左子樹;(2)訪問根結點;(3)中序遍歷右子樹。中(根)序的遍歷算法:中(根)序的遍歷算法:數(shù)據(jù)結構二叉樹教學 若二叉樹為空樹,則空操作;否則,(1)后序遍歷左子樹;

19、(2)后序遍歷右子樹;(3)訪問根結點。后(根)序的遍歷算法:后(根)序的遍歷算法:數(shù)據(jù)結構二叉樹教學ABCDEFGHK例如:例如:先序序列:先序序列:中序序列:中序序列:后序序列:后序序列:A B C D E F G H KB D C A E H G K FD C B H K G F E A數(shù)據(jù)結構二叉樹教學三、算法的遞歸描述三、算法的遞歸描述void Preorder (BiTree T, void( *visit)(TElemType& e) / 先序遍歷二叉樹 if (T) visit(T-data); / 訪問結點 Preorder(T-lchild, visit); / 遍

20、歷左子樹 Preorder(T-rchild, visit);/ 遍歷右子樹 數(shù)據(jù)結構二叉樹教學四、中序遍歷算法的非遞歸描述四、中序遍歷算法的非遞歸描述有兩種分析(描述)方法:一、“任務書”分析方法二、“路徑”分析方法數(shù)據(jù)結構二叉樹教學在寫算法之前首先需定義棧的元素類型。typedeftypedef enum Travel, Visit TaskType; / Travel = 1:遍歷, / Visit = 0:訪問 typedef struct typedef struct BiTree ptr; / 指向根結點的指針 TaskType task; / 任務性質 ElemType;“遍歷二

21、叉樹遍歷二叉樹”包括三項子任務:“遍歷左子樹”“遍歷右子樹”“訪問根結點”數(shù)據(jù)結構二叉樹教學voidvoid InOrder_iter( BiTree BT ) / 利用棧實現(xiàn)中序遍歷二叉樹,T為指向二叉樹的根結點的頭指針 InitStack(S); e.ptr=BT; e.task=Travel; ifif(T) Push(S, e); / 布置初始任務 whilewhile(! !StackEmpty(S) Pop(S,e); / 每次處理一項任務 if if (e.task=Visit) visit(e.ptr); / 處理訪問任務 elseelse ifif(! !e.ptr) / 處

22、理非空樹的遍歷任務 p=e.ptr; e.ptr=p-rchild; Push(S,e);/ 最不迫切任務進棧 e.ptr=p; e.task=Visit; Push(S,e); e.ptr=p-lchild; e.task=Travel; Push(S,e); /if /while /InOrder_iter數(shù)據(jù)結構二叉樹教學void Inorder_I(BiTree T, void (*visit) (TelemType& e) Stack *S; t = GoFarLeft(T, S); / 找到最左下的結點 while(t) visit(t-data); if (t-rchil

23、d) else if ( !StackEmpty(S ) t = Pop(S); / 退棧 else t = NULL; / ??毡砻鞅闅v結束 / while/ Inorder_I t = GoFarLeft(t-rchild, S);數(shù)據(jù)結構二叉樹教學BiTNode *GoFarLeft(BiTree T, Stack *S) if (!T ) return NULL; while (T-lchild ) Push(S, T); T = T-lchild; return T;數(shù)據(jù)結構二叉樹教學四四、遍歷算法的應用舉例遍歷算法的應用舉例2、統(tǒng)計二叉樹中葉子結點的個數(shù)、統(tǒng)計二叉樹中葉子結點的個數(shù)

24、3、求二叉樹的深度、求二叉樹的深度(后序遍歷后序遍歷)4、復制二叉樹、復制二叉樹(后序遍歷后序遍歷)5 5、建立二叉樹的存儲結構、建立二叉樹的存儲結構1、查詢二叉樹中某個結點、查詢二叉樹中某個結點數(shù)據(jù)結構二叉樹教學1. 在二叉樹不空的前提下,和根結點的元素進行比較,若相等,則找到返回 TRUE;2. 否則在左子樹中進行查找,若找到,則返回 TRUE;3. 否則繼續(xù)在右子樹中進行查找,若找到,則返回 TRUE,否則返回 FALSE;數(shù)據(jù)結構二叉樹教學Status Preorder (BiTree T, ElemType x, BiTree &p) / 若二叉樹中存在和若二叉樹中存在和 x

25、 相同的元素,則相同的元素,則 p p 指向該結點并返回指向該結點并返回 OK,/ 否則返回否則返回 FALSE if (T) if (T-data=x) p = T; return OK, /if else return FALSE;else if (Preorder(T-lchild, x, p) return OK; else return(Preorder(T-rchild, x, p) ;/else數(shù)據(jù)結構二叉樹教學2、統(tǒng)計二叉樹中葉子結點的個數(shù)、統(tǒng)計二叉樹中葉子結點的個數(shù)算法基本思想算法基本思想: : 先序(或中序或后序)遍歷二叉樹,在遍歷過程中查找葉子結點,并計數(shù)。由此,需在遍歷

26、算法中增添一個需在遍歷算法中增添一個“計數(shù)計數(shù)”的參數(shù),的參數(shù),并將算法中“訪問結點” 的操作改為:若是葉子,則計數(shù)器增若是葉子,則計數(shù)器增1 1。數(shù)據(jù)結構二叉樹教學void CountLeaf (BiTree T, int& count) if ( T ) if (!T-lchild)& (!T-rchild) count+; / 對葉子結點計數(shù) CountLeaf( T-lchild, count); CountLeaf( T-rchild, count); / if / CountLeaf數(shù)據(jù)結構二叉樹教學int CountLeaf (BiTree T)/返回指針T所指二

27、叉樹中所有葉子結點個數(shù) if (!T ) return 0; if (!T-lchild & !T-rchild) return 1; else m = CountLeaf( T-lchild); n = CountLeaf( T-rchild); return (m+n); /else / CountLeaf數(shù)據(jù)結構二叉樹教學int Count (BiTree T)/返回指針T所指二叉樹中所有結點個數(shù) if (!T ) return 0; if (!T-lchild & !T-rchild) return 1; else m = Count ( T-lchild); n =

28、Count ( T-rchild); return (m+n+1); /else / CountLeaf數(shù)據(jù)結構二叉樹教學3、求二叉樹的深度、求二叉樹的深度(后序遍歷后序遍歷)算法基本思想算法基本思想: : 從二叉樹深度的定義可知,二叉樹的二叉樹的深度應為其左、右子樹深度的最大值加深度應為其左、右子樹深度的最大值加1 1。由此,需先分別求得左、右子樹的深度,需先分別求得左、右子樹的深度,算法中“訪問結點”的操作為:求得左、求得左、右子樹深度的最大值,然后加右子樹深度的最大值,然后加 1 1 。 首先分析二叉樹的深度二叉樹的深度和它的左左、右子右子樹深度樹深度之間的關系。數(shù)據(jù)結構二叉樹教學int

29、 Depth (BiTree T ) / 返回二叉樹的深度 if ( !T ) depthval = 0; else depthLeft = Depth( T-lchild ); depthRight= Depth( T-rchild ); depthval = 1 + (depthLeft depthRight ? depthLeft : depthRight); return depthval;數(shù)據(jù)結構二叉樹教學void Depth(BiTree T , int level, int &dval) if ( T ) if (leveldval) dval = level; Dept

30、h( T-lchild, level+1, dval ); Depth( T-rchild, level+1, dval ); / 調用之前 level 的初值為 1。 / dval 的初值為 0.數(shù)據(jù)結構二叉樹教學4、復制二叉樹、復制二叉樹其基本操作為其基本操作為: :生成一個結點。生成一個結點。根元素根元素T左子樹左子樹右子樹右子樹根元素根元素NEWT左子樹左子樹右子樹右子樹左子樹左子樹右子樹右子樹(后序遍歷后序遍歷)數(shù)據(jù)結構二叉樹教學BiTNode *GetTreeNode(TElemType item, BiTNode *lptr , BiTNode *rptr ) if (!(T =

31、 new BiTNode) exit(1); T- data = item; T- lchild = lptr; T- rchild = rptr; return T; 生成一個二叉樹的結點生成一個二叉樹的結點(其數(shù)據(jù)域為其數(shù)據(jù)域為item,左指針域為左指針域為lptr,右指針域為右指針域為rptr)數(shù)據(jù)結構二叉樹教學BiTNode *CopyTree(BiTNode *T) if (!T ) return NULL; if (T-lchild ) newlptr = CopyTree(T-lchild); /復制左子樹 else newlptr = NULL; if (T-rchild )

32、newrptr = CopyTree(T-rchild); /復制右子樹 else newrptr = NULL; newT = GetTreeNode(T-data, newlptr, newrptr); return newT; / CopyTree數(shù)據(jù)結構二叉樹教學ABCDEFGHK D C H K G A例如例如: :下列二叉樹下列二叉樹的復制過程如下的復制過程如下: :newT F B E 數(shù)據(jù)結構二叉樹教學5 5、建立二叉樹的存儲、建立二叉樹的存儲結構結構不同的定義方法相應有不同的不同的定義方法相應有不同的存儲結構的建立算法存儲結構的建立算法數(shù)據(jù)結構二叉樹教學 以字符串的形式以字符

33、串的形式 “根根 左子樹左子樹 右子樹右子樹”定義一棵二叉樹定義一棵二叉樹例如例如: :以空白字符“ ”表示ABCDA(B( ,C( , ),D( , )空樹空樹只含一個根結點只含一個根結點的二叉樹的二叉樹A以字符串“A ”表示以下列字符串表示數(shù)據(jù)結構二叉樹教學Status CreateBiTree(BiTree &T) scanf(&ch); if (ch= ) T = NULL; else if (!(T = new BiTNode) exit(OVERFLOW); T-data = ch; / 生成根結點 CreateBiTree(T-lchild); / 構造左子樹 C

34、reateBiTree(T-rchild); / 構造右子樹 return OK; / CreateBiTree數(shù)據(jù)結構二叉樹教學A B C D A BCD上頁算法執(zhí)行過程舉例如下:ATBCDscanf(&ch);if (ch= ) T = NULL;else if (!(T = new BiTNode) exit(OVERFLOW); T-data = ch;CreateBiTree(T-lchild); CreateBiTree(T-rchild);數(shù)據(jù)結構二叉樹教學 按給定的表達式建相應二叉樹按給定的表達式建相應二叉樹 由先綴表示式建樹由先綴表示式建樹例如:已知表達式的先綴表示式

35、 - -+ + a b c / d e 由原表達式建樹由原表達式建樹例如:已知表達式 (a+b)c d/e d/e數(shù)據(jù)結構二叉樹教學對應先綴表達式 - -+ + a b c / d e的二叉樹的二叉樹abcde- -+/特點特點: 操作數(shù)為葉子葉子結點, 運算符為分支分支結點數(shù)據(jù)結構二叉樹教學scanf(&ch);if ( In(ch, 字母集 ) 建葉子結點;else 建根結點; 遞歸建左子樹; 遞歸建右子樹;由先綴表示式建樹的算法的基本操作:由先綴表示式建樹的算法的基本操作:數(shù)據(jù)結構二叉樹教學a+b(a+b)c d/e d/ea+bc 分析表達式和二叉樹的關系分析表達式和二叉樹的關

36、系:abbac+abc(a+b)c/deabc+- -數(shù)據(jù)結構二叉樹教學基本操作基本操作:scanf(&ch);if (In(ch, 字母集 ) 建葉子結點; 暫存; else if (In(ch, 運算符集) 和前一個運算符比較優(yōu)先數(shù); 若當前的優(yōu)先數(shù)“高”,則暫存; 否則建子樹;數(shù)據(jù)結構二叉樹教學void CrtExptree(BiTree &T, char exp ) InitStack(S); Push(S, #); InitStack(PTR); p = exp; ch = *p; while (!(GetTop(S)=# & ch=#) if (!IN(ch

37、, OP) CrtNode( t, ch ); / 建葉子結點并入棧 else if ( ch!= # ) p+; ch = *p; / while Pop(PTR, T); / CrtExptree 數(shù)據(jù)結構二叉樹教學switch (ch) case ( : Push(S, ch); break; case ) : Pop(S, c); while (c!= ( ) CrtSubtree( t, c); / 建二叉樹并入棧建二叉樹并入棧 Pop(S, c) break; defult : / switch 數(shù)據(jù)結構二叉樹教學while(!Gettop(S, c) & ( preced

38、e(c,ch) CrtSubtree( t, c); Pop(S, c);if ( ch!= # ) Push( S, ch); break;數(shù)據(jù)結構二叉樹教學建葉子結點的算法為:void CrtNode(BiTree& T,char ch) if (!(T= new BiTNode) exit(OVERFLOW); T-data = char; T-lchild = T-rchild = NULL; Push( PTR, T );數(shù)據(jù)結構二叉樹教學建子樹的算法為:void CrtSubtree (Bitree& T, char c) if (!(T= new BiTNode)

39、 exit(OVERFLOW); T-data = c; Pop(PTR, rc); T-rchild = rc; Pop(PTR, lc); T-lchild = lc; Push(PTR, T);數(shù)據(jù)結構二叉樹教學 僅知二叉樹的先序序列“abcdefg” 不能唯一確定一棵二叉樹,由二叉樹的先序和中序序列建樹由二叉樹的先序和中序序列建樹 如果同時已知二叉樹的中序序列“cbdaegf”,則會如何? 二叉樹的先序序列二叉樹的中序序列左子樹左子樹左子樹左子樹 右子樹右子樹右子樹右子樹根根根根數(shù)據(jù)結構二叉樹教學a b c d e f gc b d a e g f例如例如: :aab bccddeef

40、fggabcdefg先序序列中序序列數(shù)據(jù)結構二叉樹教學void CrtBT(BiTree& T, char pre, char ino, int ps, int is, int n ) / 已知preps.ps+n-1為二叉樹的先序序列, / insis.is+n-1為二叉樹的中序序列,本算 / 法由此兩個序列構造二叉鏈表 if (n=0) T=NULL; else k=Search(ino, preps); / 在中序序列中查詢 if (k= -1) T=NULL; else / / CrtBT 數(shù)據(jù)結構二叉樹教學if (!(T= new BiTNode) exit(OVERFLOW

41、);T-data = preps;if (k=is) T-Lchild = NULL;else CrtBT(T-Lchild, pre, ino, ps+1, is, k-is );if (k=is+n-1) T-Rchild = NULL;else CrtBT(T-Rchild, pre, ino, ps+1+(k-is), k+1, n-(k-is)-1 );數(shù)據(jù)結構二叉樹教學6.5線索二叉樹線索二叉樹 何謂線索二叉樹?何謂線索二叉樹? 線索鏈表的遍歷算法線索鏈表的遍歷算法 如何建立線索鏈表?如何建立線索鏈表?數(shù)據(jù)結構二叉樹教學一、一、何謂線索二叉樹?何謂線索二叉樹?遍歷二叉樹的結果是,

42、求得結點的一個線性序列。ABCDEFGHK例如:先序先序序列: A B C D E F G H K中序中序序列: B D C A H G K F E后序后序序列: D C B H K G F E A數(shù)據(jù)結構二叉樹教學指向該線性序列中的“前驅”和 “后繼” 的指針指針,稱作“線線索索”與其相應的二叉樹,稱作 “線索二叉樹線索二叉樹”包含 “線索” 的存儲結構,稱作 “線索鏈線索鏈表表”A B C D E F G H K D C B E 數(shù)據(jù)結構二叉樹教學對對線索鏈表線索鏈表中結點的約定:中結點的約定: 在二叉鏈表的結點中增加兩個標志域增加兩個標志域,并作如下規(guī)定:若該結點的左子樹不空,若該結點的

43、左子樹不空,則Lchild域的指針指向其左子樹, 且左標志域的值為“指針 Link”; 否則,Lchild域的指針指向其“前驅”, 且左標志的值為“線索 Thread” 。數(shù)據(jù)結構二叉樹教學若該結點的右子樹不空,若該結點的右子樹不空,則rchild域的指針指向其右子樹, 且右標志域的值為 “指針 Link”;否則,rchild域的指針指向其“后繼”, 且右標志的值為“線索 Thread”。 如此定義的二叉樹的存儲結構稱作如此定義的二叉樹的存儲結構稱作“線索鏈表線索鏈表”數(shù)據(jù)結構二叉樹教學typedef struct BiThrNod TElemType data; struct BiThrNo

44、de *lchild, *rchild; / 左右指針 PointerThr LTag, RTag; / 左右標志 BiThrNode, *BiThrTree;線索鏈表的類型描述: typedef enum Link, Thread PointerThr; / Link=0:指針,Thread=1:線索數(shù)據(jù)結構二叉樹教學二、線索鏈表的遍歷算法二、線索鏈表的遍歷算法: for ( p = firstNode(T); p; p = Succ(p) ) Visit (p);由于在線索鏈表中添加了遍歷中得到的“前驅”和“后繼”的信息,從而簡化了遍歷的算法。數(shù)據(jù)結構二叉樹教學例如例如: 對中序線索化鏈表

45、的遍歷算法對中序線索化鏈表的遍歷算法 中序遍歷的第一個結點中序遍歷的第一個結點 ? 在中序線索化鏈表中結點的后繼在中序線索化鏈表中結點的后繼 ?左子樹上處于“最左下最左下”(沒有左子樹)的結點若若無右子樹,則為則為后繼線索后繼線索所指結點否則為否則為對其右子樹右子樹進行中序遍歷遍歷時訪問的第一個結點第一個結點數(shù)據(jù)結構二叉樹教學void InOrderTraverse_Thr(BiThrTree T, void (*Visit)(TElemType e) p = T-lchild; / p指向根結點 while (p != T) / 空樹或遍歷結束時,p=T while (p-LTag=Link

46、) p = p-lchild; / 第一個結點 while (p-RTag=Thread & p-rchild!=T) p = p-rchild; Visit(p-data); / 訪問后繼結點 p = p-rchild; / p進至其右子樹根 / InOrderTraverse_Thr數(shù)據(jù)結構二叉樹教學 在中序遍歷過程中修改結點的在中序遍歷過程中修改結點的左、右指針域,以保存當前訪問結左、右指針域,以保存當前訪問結點的點的“前驅前驅”和和“后繼后繼”信息。遍歷過信息。遍歷過程中,附設指針程中,附設指針pre, 并始終保持指并始終保持指針針pre指向當前訪問的、指針指向當前訪問的、指針

47、p所指所指結點的前驅。結點的前驅。三、如何建立線索鏈表?三、如何建立線索鏈表?數(shù)據(jù)結構二叉樹教學void InThreading(BiThrTree p) if (p) / 對以p為根的非空二叉樹進行線索化 InThreading(p-lchild); / 左子樹線索化 if (!p-lchild) / 建前驅線索 p-LTag = Thread; p-lchild = pre; if (!pre-rchild) / 建后繼線索 pre-RTag = Thread; pre-rchild = p; pre = p; / 保持 pre 指向 p 的前驅 InThreading(p-rchild)

48、; / 右子樹線索化 / if / InThreading數(shù)據(jù)結構二叉樹教學Status InOrderThreading(BiThrTree &Thrt, BiThrTree T) / 構建中序線索鏈表 if (!(Thrt = new BiThrNode) ) exit (OVERFLOW); Thrt-LTag = Link; Thrt-RTag =Thread; Thrt-rchild = Thrt; / 添加頭結點 return OK; / InOrderThreading 數(shù)據(jù)結構二叉樹教學if (!T) Thrt-lchild = Thrt; else Thrt-lchi

49、ld = T; pre = Thrt; InThreading(T); pre-rchild = Thrt; / 處理最后一個結點 pre-RTag = Thread; Thrt-rchild = pre; 數(shù)據(jù)結構二叉樹教學 6.6 樹和森林樹和森林 的表示方法的表示方法數(shù)據(jù)結構二叉樹教學樹的三種存儲結構樹的三種存儲結構一、一、雙親表示法雙親表示法二、二、孩子鏈表表示法孩子鏈表表示法三、三、樹的二叉鏈表樹的二叉鏈表( (孩子孩子- -兄弟)兄弟) 存儲表示法存儲表示法數(shù)據(jù)結構二叉樹教學ABCDEFGr=0n=60 A -11 B 02 C 03 D 04 E 2 5 F 26 G 5data

50、 parent一、雙親表示法一、雙親表示法:數(shù)據(jù)結構二叉樹教學 typedef struct PTNode Elem data; int parent; / 雙親位置域 PTNode; data parent#define MAX_TREE_SIZE 100結點結構結點結構:C語言的類型描述語言的類型描述: :數(shù)據(jù)結構二叉樹教學typedef struct PTNode nodes MAX_TREE_SIZE; int r, n; / 根結點的位置和結點個數(shù) PTree;樹結構樹結構:數(shù)據(jù)結構二叉樹教學r=0n=6 data firstchildABCDEFG0 A -11 B 02 C 03

51、 D 04 E 25 F 26 G 464 5 1 2 3二、孩子鏈表表示法二、孩子鏈表表示法:-1 0 0 0 2 2 4數(shù)據(jù)結構二叉樹教學typedef struct CTNode int child; struct CTNode *nextchild; *ChildPtr;孩子結點結構孩子結點結構: child nextchildC語言的類型描述語言的類型描述: :數(shù)據(jù)結構二叉樹教學 typedef struct Elem data; ChildPtr firstchild; / 孩子鏈的頭指針 CTBox;雙親結點結構雙親結點結構 data firstchild數(shù)據(jù)結構二叉樹教學typ

52、edef struct CTBox nodesMAX_TREE_SIZE; int n, r; / 結點數(shù)和根結點的位置 CTree;樹結構樹結構:數(shù)據(jù)結構二叉樹教學ABCDEFGroot AB C E D F G AB C E D F G 三、樹的二叉鏈表三、樹的二叉鏈表 (孩子孩子-兄弟)存儲表示法兄弟)存儲表示法root數(shù)據(jù)結構二叉樹教學typedef struct CSNode Elem data; struct CSNode *firstchild, *nextsibling; CSNode, *CSTree;C語言的類型描述語言的類型描述: :結點結構結點結構: firstchil

53、d data nextsibling數(shù)據(jù)結構二叉樹教學 森林和二叉樹的對應關系森林和二叉樹的對應關系設設森林森林 F = ( T1, T2, , Tn ); T1 = ( root,t11, t12, , t1m );二叉樹二叉樹 B =( LBT, Node(root), RBT );數(shù)據(jù)結構二叉樹教學由森林轉換成二叉樹由森林轉換成二叉樹的轉換規(guī)則為:若 F = ,則 B = ; 由 ROOT( T1 ) 對應得到Node(root);否則,由 (t11, t12, , t1m ) 對應得到 LBT;由 (T2, T3, Tn ) 對應得到 RBT。數(shù)據(jù)結構二叉樹教學由二叉樹轉換為森林由二叉

54、樹轉換為森林的轉換規(guī)則為:由LBT 對應得到 ( t11, t12, ,t1m);若 B = , 則 F = ;否則,由 Node(root) 對應得到 ROOT( T1 );由RBT 對應得到 (T2, T3, , Tn)。數(shù)據(jù)結構二叉樹教學T1T11,T12,T1mT2,TnLBTRBTroot數(shù)據(jù)結構二叉樹教學 由此,樹和森林的各種操作均可與二叉樹的各種操作相對應。 應當注意的是,應當注意的是,和樹對應的二叉樹,其左、右子樹的概念已改變?yōu)椋?左是孩子,右是兄弟左是孩子,右是兄弟數(shù)據(jù)結構二叉樹教學6.7樹和森林的遍歷樹和森林的遍歷數(shù)據(jù)結構二叉樹教學一、樹的遍歷一、樹的遍歷二、森林的遍歷二、

55、森林的遍歷三、樹的遍歷的應用三、樹的遍歷的應用數(shù)據(jù)結構二叉樹教學樹的遍歷可有樹的遍歷可有2條搜索路徑條搜索路徑:按層次遍歷按層次遍歷:先根先根(次序次序)遍歷遍歷:后根后根(次序次序)遍歷遍歷: 若樹不空,則先訪問根結點,然后若樹不空,則先訪問根結點,然后依次先根遍歷各棵子樹。依次先根遍歷各棵子樹。 若樹不空,則先依次后根遍歷各棵若樹不空,則先依次后根遍歷各棵子樹,然后訪問根結點。子樹,然后訪問根結點。 若樹不空,則自上而下自左至右若樹不空,則自上而下自左至右訪問樹中每個結點。訪問樹中每個結點。數(shù)據(jù)結構二叉樹教學 層次遍歷時頂點層次遍歷時頂點的訪問次序:的訪問次序: A B C DE F G

56、H I J K 先根遍歷時頂點先根遍歷時頂點的訪問次序:的訪問次序:A B E F C D G H I J K 后根遍歷時頂點后根遍歷時頂點的訪問次序:的訪問次序:E F B C I J K H G D AA B C D E F G H I J K數(shù)據(jù)結構二叉樹教學 B C DE F G H I J K1。森林中第一棵樹的根結點;2。森林中第一棵樹的子樹森林;3。森林中其它樹構成的森林??梢苑纸獬扇糠郑荷稚謹?shù)據(jù)結構二叉樹教學 若森林不空,則訪問訪問森林中第一棵樹的根結點;先序遍歷先序遍歷森林中第一棵樹的子樹森林;先序遍歷先序遍歷森林中(除第一棵樹之外)其 余樹構成的森林。先序遍歷先序遍歷

57、森林的遍歷森林的遍歷即:依次從左至右依次從左至右對森林中的每一棵樹樹進行先根遍歷先根遍歷。數(shù)據(jù)結構二叉樹教學 中序遍歷中序遍歷 若森林不空,則中序遍歷中序遍歷森林中第一棵樹的子樹森林;訪問訪問森林中第一棵樹的根結點;中序遍歷中序遍歷森林中(除第一棵樹之外)其 余樹構成的森林。即:依次從左至右依次從左至右對森林中的每一棵樹樹進行后根遍歷后根遍歷。數(shù)據(jù)結構二叉樹教學 樹的遍歷和二叉樹遍歷樹的遍歷和二叉樹遍歷的對應關系的對應關系 ?先根遍歷先根遍歷后根遍歷后根遍歷樹樹二叉樹二叉樹森林森林先序遍歷先序遍歷先序遍歷先序遍歷中序遍歷中序遍歷中序遍歷中序遍歷數(shù)據(jù)結構二叉樹教學設樹的存儲結構為孩子兄弟鏈表設樹

58、的存儲結構為孩子兄弟鏈表typedef struct CSNode Elem data; struct CSNode *firstchild, *nextsibling; CSNode, *CSTree;一、求樹的深度一、求樹的深度二、輸出樹中所有從根到葉子的路徑二、輸出樹中所有從根到葉子的路徑三、建樹的存儲結構三、建樹的存儲結構數(shù)據(jù)結構二叉樹教學Int Depth(CSTree T)If (T=NULL) return 0;ElseD1 = Depth(T-firstchild);D2 = Depth(T-nextsibling);Return Maxd1+1,d2數(shù)據(jù)結構二叉樹教學int

59、TreeDepth( CTree T ) / T 是樹的孩子鏈表存儲結構, / 返回該樹的深度 if ( T.n = 0) return 0; else return Depth( T, T.r ); / TreeDepth一、求樹的深度的算法:一、求樹的深度的算法:數(shù)據(jù)結構二叉樹教學int Depth( CTree T, int root ) max = 0; p = T.nodesroot.firstchild; while ( p ) h = Depth( T, p-child ); if ( h max ) max = h; p = p-nextchild; /while return

60、 max+1;數(shù)據(jù)結構二叉樹教學二、二、輸出樹中所有從根到葉子的路徑的算法輸出樹中所有從根到葉子的路徑的算法: A B C DE F G H I J K例如:對左圖所示的樹,其輸出結果應為:A B EA B FA CA D G H IA D G H JA D G H K數(shù)據(jù)結構二叉樹教學void AllPath( BiTree T, Stack& S ) if (T) Push( S, T-data ); if (!T-Lchild & !T-Rchild ) PrintStack(S); else AllPath( T-Lchild, S ); AllPath( T-Rchild, S ); Pop(S); / if(T) / AllPath/ 輸出二叉樹上從根到所有葉子結點的路徑輸出二叉樹上從根到所有葉子結點的路徑數(shù)據(jù)結構二叉樹教學void OutPath( Bitree T, Stack& S ) while ( !T ) Push(S, T-data );

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論