課件第6二叉樹_第1頁
課件第6二叉樹_第2頁
課件第6二叉樹_第3頁
課件第6二叉樹_第4頁
課件第6二叉樹_第5頁
已閱讀5頁,還剩54頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、第第6章章 樹和二叉樹樹和二叉樹n學(xué)習(xí)要點學(xué)習(xí)要點: 熟練掌握二叉樹的結(jié)構(gòu)特性熟練掌握二叉樹的結(jié)構(gòu)特性熟悉二叉樹的各種存儲結(jié)構(gòu)特點及使用范圍熟悉二叉樹的各種存儲結(jié)構(gòu)特點及使用范圍熟練掌握各種遍歷策略的遞歸和非遞歸算法,靈熟練掌握各種遍歷策略的遞歸和非遞歸算法,靈活運用遍歷算法實現(xiàn)二叉樹的其他操作活運用遍歷算法實現(xiàn)二叉樹的其他操作熟練掌握二叉樹的線索化過程以及在中序線索化熟練掌握二叉樹的線索化過程以及在中序線索化樹上找給定結(jié)點的前驅(qū)和后繼的方法樹上找給定結(jié)點的前驅(qū)和后繼的方法掌握樹和森林與二叉樹的轉(zhuǎn)換方法掌握樹和森林與二叉樹的轉(zhuǎn)換方法學(xué)會編寫實現(xiàn)樹的各種操作的算法學(xué)會編寫實現(xiàn)樹的各種操作的算法了

2、解最優(yōu)樹的特性,掌握建立最優(yōu)樹和哈夫曼編了解最優(yōu)樹的特性,掌握建立最優(yōu)樹和哈夫曼編碼的方法碼的方法6.1 樹的定義和基本術(shù)語樹的定義和基本術(shù)語6.1.1 樹的定義樹的定義n樹型結(jié)構(gòu):樹型結(jié)構(gòu):非線性結(jié)構(gòu):至少存在一個數(shù)據(jù)元素有非線性結(jié)構(gòu):至少存在一個數(shù)據(jù)元素有兩個兩個或或兩兩個以上個以上的的直接前驅(qū)直接前驅(qū)(或或直接后繼直接后繼)元素的數(shù)據(jù)結(jié)構(gòu)。元素的數(shù)據(jù)結(jié)構(gòu)。用于描述層次結(jié)構(gòu)的關(guān)系:用于描述層次結(jié)構(gòu)的關(guān)系:n人類的族譜、操作系統(tǒng)的文件系統(tǒng)、人類的族譜、操作系統(tǒng)的文件系統(tǒng)、Internet中的中的DNS(域名系統(tǒng)域名系統(tǒng))等等分等級的分類方案均可用層次結(jié)構(gòu)來表示,可由分等級的分類方案均可用層次

3、結(jié)構(gòu)來表示,可由此導(dǎo)出樹型結(jié)構(gòu)。此導(dǎo)出樹型結(jié)構(gòu)。n樹的定義:樹的定義: 是是n(n0)個結(jié)點的有限集合個結(jié)點的有限集合T,對于任意一棵,對于任意一棵非空樹,它滿足:非空樹,它滿足:有且有且僅有一個僅有一個特定的稱為特定的稱為根根(root)的結(jié)點;的結(jié)點;當(dāng)當(dāng)n1時,其余結(jié)點可分為時,其余結(jié)點可分為m(m0)個個互不相交的互不相交的有限集有限集T1,T2,.,Tm,其中每個集合本身又是,其中每個集合本身又是一棵樹,稱為根的一棵樹,稱為根的子樹子樹。上述上述樹的定義是一個遞歸定義樹的定義是一個遞歸定義。例如:例如:ABCDEFGHIJMKLAn樹的類型定義:樹的類型定義:ADT Tree 數(shù)據(jù)對

4、象數(shù)據(jù)對象:D是具有相同特性的數(shù)據(jù)元素的集合。是具有相同特性的數(shù)據(jù)元素的集合。 數(shù)據(jù)關(guān)系數(shù)據(jù)關(guān)系:若若D為空集,則稱為空樹;否則為空集,則稱為空樹;否則: (1) 在在D中存在唯一的稱為根的數(shù)據(jù)元素中存在唯一的稱為根的數(shù)據(jù)元素root, (2) 當(dāng)當(dāng)n1時,其余結(jié)點可分為時,其余結(jié)點可分為m (m0)個互不相個互不相交的有限集交的有限集T1, T2, , Tm, 其中每一棵子集本身又其中每一棵子集本身又是一棵符合本定義的樹,稱為根是一棵符合本定義的樹,稱為根root的子樹。的子樹。 基本操作基本操作:n查找類查找類n插入插入 n刪除刪除 ADT Tree查找類:查找類:nRoot(T) / 求

5、樹的根結(jié)點求樹的根結(jié)點 nValue(T, cur_e) / 求當(dāng)前結(jié)點的元素值求當(dāng)前結(jié)點的元素值nParent(T, cur_e) / 求當(dāng)前結(jié)點的雙親結(jié)點求當(dāng)前結(jié)點的雙親結(jié)點nLeftChild(T, cur_e) / 求當(dāng)前結(jié)點的最左孩子求當(dāng)前結(jié)點的最左孩子nRightSibling(T, cur_e) / 求當(dāng)前結(jié)點的右兄弟求當(dāng)前結(jié)點的右兄弟nTreeEmpty(T) / 判定樹是否為空樹判定樹是否為空樹nTreeDepth(T) / 求樹的深度求樹的深度nTraverseTree( T, Visit() ) / 遍歷遍歷插入:插入:nInitTree(&T) / 初始化置空樹

6、初始化置空樹nCreateTree(&T, definition) / 按定義構(gòu)造按定義構(gòu)造nAssign(T, cur_e, value) / 給當(dāng)前結(jié)點賦值給當(dāng)前結(jié)點賦值nInsertChild(&T, &p, i, c) / 將以將以c為根的樹插入為結(jié)為根的樹插入為結(jié) /點點p的第的第i棵子樹棵子樹刪除:刪除:nClearTree(&T) / 將樹清空將樹清空nDestroyTree(&T) / 銷毀樹的結(jié)構(gòu)銷毀樹的結(jié)構(gòu)nDeleteChild(&T, &p, i) / 刪除結(jié)點刪除結(jié)點p的第的第i棵子棵子例如:例如:ABCDEFG

7、HIJMKL(A( B(E, F(K, L), C(G), D(H, I, J(M) )T1T3T2樹根樹根T1T2T36.1.2 基本術(shù)語基本術(shù)語n結(jié)點結(jié)點:包含一個數(shù)據(jù)元素包含一個數(shù)據(jù)元素及及若干指向其子樹的分若干指向其子樹的分支。支。n結(jié)點的度結(jié)點的度:結(jié)點擁有的:結(jié)點擁有的子樹數(shù)子樹數(shù)。如圖:如圖: A的度為的度為3, C的度為的度為1, E的度為的度為0。n葉子葉子(或終端或終端)結(jié)點:度為零的結(jié)點。結(jié)點:度為零的結(jié)點。n分支分支(或非終端或非終端)結(jié)點:度大于零的結(jié)點。結(jié)點:度大于零的結(jié)點。ABCDEFGHIJMKLn樹的度樹的度:樹中所有結(jié)點的:樹中所有結(jié)點的度的最大值度的最大值

8、。n結(jié)點的結(jié)點的子樹的根子樹的根稱為該結(jié)點的稱為該結(jié)點的孩子孩子(child) 。n相應(yīng)的,該結(jié)點相應(yīng)的,該結(jié)點稱為孩子的稱為孩子的雙親雙親(parent)。如圖所示,樹的度為如圖所示,樹的度為3;D為為A的子樹的子樹T3的根,則的根,則D是是A的孩子,而的孩子,而A則是則是D的雙親。的雙親。n同一個雙親同一個雙親的孩子之間互的孩子之間互 稱稱兄弟兄弟。如圖所示中,如圖所示中,H、I、J互稱為兄弟。互稱為兄弟。ABCDEFGHIJMKLE、G、H互稱兄弟?互稱兄弟?n雙親在同一層的結(jié)點互為雙親在同一層的結(jié)點互為堂兄弟堂兄弟。n結(jié)點的層次結(jié)點的層次:根結(jié)點的層次為:根結(jié)點的層次為1,第,第l層的

9、結(jié)點的層的結(jié)點的子樹的根結(jié)點的層次為子樹的根結(jié)點的層次為l+1。n樹的深度樹的深度:樹中:樹中葉子結(jié)點葉子結(jié)點所在的所在的最大層次最大層次。n森林森林:是:是m(m0)棵棵互不相交的互不相交的樹的集合。樹的集合。n任何一棵非空樹是一個任何一棵非空樹是一個二元組二元組Tree = (root,F(xiàn))其中:其中: root 被稱為根結(jié)點被稱為根結(jié)點 F 被稱為被稱為子樹森林子樹森林ArootBCDEFGHIJMKLFn有序樹有序樹:子樹之間存在確定的次序關(guān)系。:子樹之間存在確定的次序關(guān)系。(樹中結(jié)樹中結(jié)點的各子樹從左到右是有次序的,即不能互換點的各子樹從左到右是有次序的,即不能互換)。n無序樹無序樹

10、:子樹之間不存在確定的次序關(guān)系。:子樹之間不存在確定的次序關(guān)系。n樹型結(jié)構(gòu)和線性結(jié)構(gòu)的特點:樹型結(jié)構(gòu)和線性結(jié)構(gòu)的特點:線性結(jié)構(gòu)線性結(jié)構(gòu)樹型結(jié)構(gòu)樹型結(jié)構(gòu)第一個數(shù)據(jù)元素第一個數(shù)據(jù)元素 ( (無前驅(qū)無前驅(qū)) ) 根結(jié)點根結(jié)點 ( (無前驅(qū)無前驅(qū)) )最后一個數(shù)據(jù)元素最后一個數(shù)據(jù)元素 (無后繼無后繼)多個葉子結(jié)點多個葉子結(jié)點 ( (無后繼無后繼) )其它數(shù)據(jù)元素其它數(shù)據(jù)元素( (一個前驅(qū)、一個前驅(qū)、 一個后繼一個后繼) )其它數(shù)據(jù)元素其它數(shù)據(jù)元素( (一個前驅(qū)、一個前驅(qū)、 多個后繼多個后繼) )6.2.1 二叉樹的定義二叉樹的定義n定義定義:是:是n(n=0)個結(jié)點的有限集合,它或為個結(jié)點的有限集合,

11、它或為空樹空樹(n=0),或由,或由一個根結(jié)點一個根結(jié)點和和至多兩棵至多兩棵稱為根的稱為根的左子左子樹樹和和右子樹右子樹的互不相交的的互不相交的二叉樹二叉樹組成。組成。注:二叉樹中不存在度大于注:二叉樹中不存在度大于2的結(jié)點,并且二叉樹的結(jié)點,并且二叉樹的子樹有左子樹和右子樹之分。的子樹有左子樹和右子樹之分。6.2 二叉樹二叉樹ABCDEFGHK根結(jié)點根結(jié)點左子樹左子樹右子樹右子樹n二叉樹的五種基本形態(tài):二叉樹的五種基本形態(tài):N空樹空樹只含根結(jié)點只含根結(jié)點NNNLRR右子樹為空樹右子樹為空樹L左子樹為空樹左子樹為空樹左右子樹均左右子樹均不為空樹不為空樹n二叉樹的抽象數(shù)據(jù)類型定義:二叉樹的抽象數(shù)

12、據(jù)類型定義:ADT BinaryTree 數(shù)據(jù)對象數(shù)據(jù)對象:D是具有相同特性的數(shù)據(jù)元素的集合。是具有相同特性的數(shù)據(jù)元素的集合。 數(shù)據(jù)關(guān)系數(shù)據(jù)關(guān)系:若若D為空集,則稱為空樹;否則為空集,則稱為空樹;否則: (1) 在在D中存在唯一的稱為根的數(shù)據(jù)元素中存在唯一的稱為根的數(shù)據(jù)元素root, . 基本操作基本操作:n查找類查找類n插入插入 n刪除刪除ADT BinaryTree 詳細說明見教材詳細說明見教材P121P1236.2.2 二叉樹的性質(zhì)二叉樹的性質(zhì)n性質(zhì)性質(zhì)1 :在二叉樹的第在二叉樹的第 i 層上層上至多至多有有2i-1 個結(jié)點個結(jié)點(i1)。證明證明:(歸納法歸納法)歸納基:歸納基:i =

13、 1 層時,只有一個根結(jié)點:層時,只有一個根結(jié)點: 2i-1 = 20 = 1,命題成立。,命題成立。歸納假設(shè):假設(shè)對所有的歸納假設(shè):假設(shè)對所有的 j,1 j i,命題成立。命題成立。即第即第j層上至多有層上至多有2j-1個結(jié)點。個結(jié)點。歸納證明:歸納證明:j=i時,命題成立。時,命題成立。 二叉樹上每個結(jié)點二叉樹上每個結(jié)點至多有兩棵子樹至多有兩棵子樹,且由歸,且由歸納假設(shè)有:第納假設(shè)有:第i-1層上至多有層上至多有2i-2個結(jié)點個結(jié)點 第第 j=i 層的結(jié)點數(shù)至多層的結(jié)點數(shù)至多 = 2i-2 2 = 2i-1 。命題成命題成立立(證畢證畢)n性質(zhì)性質(zhì)2:深度為:深度為 k 的二叉樹上的二叉樹

14、上至多至多含含 2k-1 個結(jié)點個結(jié)點(k1)。證明:證明:基于性質(zhì)基于性質(zhì)1,深度為,深度為 k 的二叉樹上的結(jié)點數(shù)至的二叉樹上的結(jié)點數(shù)至多為:多為:20+21+ +2k-1 = 2k-1 。n性質(zhì)性質(zhì)3:對任何一棵二叉樹,若它含有對任何一棵二叉樹,若它含有n0 個葉子結(jié)個葉子結(jié)點、點、n2 個度為個度為2的結(jié)點,則必存在關(guān)系式:的結(jié)點,則必存在關(guān)系式:n0 = n2+1。證明:證明:設(shè)二叉樹上結(jié)點總數(shù)設(shè)二叉樹上結(jié)點總數(shù) n = n0 + n1 + n2, 二叉樹上分支總數(shù)二叉樹上分支總數(shù) b = n1+2n2, 而而 b = n-1 = n0 + n1 + n2 1 由由, n0 = n2

15、 + 1 。除根結(jié)點外,其余結(jié)點都有一個分支除根結(jié)點外,其余結(jié)點都有一個分支進入,設(shè)進入,設(shè)b為分支總數(shù),則為分支總數(shù),則n=b+1。n兩類兩類特殊特殊的二叉樹:的二叉樹:滿二叉樹滿二叉樹:指的是深度為:指的是深度為k且含有且含有2k-1個結(jié)點的二叉?zhèn)€結(jié)點的二叉樹。樹。完全二叉樹完全二叉樹:樹中所含的:樹中所含的 n 個結(jié)點和滿二叉樹中個結(jié)點和滿二叉樹中編編號為號為 1 至至 n 的結(jié)點的結(jié)點一一對應(yīng)。一一對應(yīng)。123456789101112131415abcdefghij特點特點:是:是每一層每一層上的結(jié)點數(shù)都是上的結(jié)點數(shù)都是最大結(jié)點數(shù)最大結(jié)點數(shù)。特點特點:葉子結(jié)點葉子結(jié)點只可能只可能在在層

16、次最大層次最大的兩層的兩層出現(xiàn);出現(xiàn);對任一結(jié)點,若其對任一結(jié)點,若其右右分支下的子孫的分支下的子孫的最大層次為最大層次為l,則其,則其左左分支下的子孫的分支下的子孫的最大層次為最大層次為l或或l+1。完全二叉樹的性質(zhì):完全二叉樹的性質(zhì):n性質(zhì)性質(zhì)4:具有具有n個結(jié)點的完全二叉樹的個結(jié)點的完全二叉樹的深度深度為為 log2n +1。證明:證明:設(shè)完全二叉樹的深度為設(shè)完全二叉樹的深度為k,則根據(jù)性質(zhì)則根據(jù)性質(zhì)2(深度深度為為k的二叉樹至多有的二叉樹至多有2k-1個結(jié)點個結(jié)點) 得得 2k-1-1 n 2k 1,或:,或: 2k-1 n 2k 即即 k-1 log2 n n,則該結(jié)點無左孩子,否則

17、,編號為,則該結(jié)點無左孩子,否則,編號為 2i 的結(jié)點為其的結(jié)點為其左孩子左孩子結(jié)點;結(jié)點;(3)若若 2i+1n,則該結(jié)點無右孩子結(jié)點,否則,編號,則該結(jié)點無右孩子結(jié)點,否則,編號為為2i+1 的結(jié)點為其的結(jié)點為其右孩子右孩子結(jié)點。結(jié)點。 i/2 i 2i 2i+1 i+1 2i+2 2i+3 i+1 2i+2 2i+3 i2i2i+1 .n性質(zhì)練習(xí):性質(zhì)練習(xí):1. 一棵二叉樹在其第五層中有一棵二叉樹在其第五層中有17個結(jié)點,可不可能?個結(jié)點,可不可能?2. 二叉樹的根結(jié)點屬于第二叉樹的根結(jié)點屬于第0層還是屬于第層還是屬于第1層?層?3. 已知一棵二叉樹有已知一棵二叉樹有20個結(jié)點,其中個結(jié)

18、點,其中6個結(jié)點為葉子,則該個結(jié)點為葉子,則該樹中度為樹中度為2的結(jié)點數(shù)為的結(jié)點數(shù)為 ?度為?度為0的結(jié)點為的結(jié)點為 ?4. 已知一棵完全二叉樹中編號為已知一棵完全二叉樹中編號為101的結(jié)點有的結(jié)點有LC和和RC結(jié)點,結(jié)點,則其則其LC結(jié)點編號為結(jié)點編號為 ,RC結(jié)點編號為結(jié)點編號為 ?5. 一棵深度為一棵深度為h的完全的完全k叉樹,如果按層次自頂向下、同一層叉樹,如果按層次自頂向下、同一層自左向右、順序從自左向右、順序從1開始對全部結(jié)點進行編號,試問:該開始對全部結(jié)點進行編號,試問:該樹上最多有多少個結(jié)點?最少有多少個結(jié)點?樹上最多有多少個結(jié)點?最少有多少個結(jié)點?第第i層上至多有層上至多有2

19、i-1個結(jié)點,則個結(jié)點,則25-1=16。所以,不可能。所以,不可能。第第1層層56由性質(zhì)由性質(zhì)3:n0=n2+1,則,則n2=n0-1=6-1=5。202203由性質(zhì)由性質(zhì)5,可知左孩子為,可知左孩子為2i,右孩子為,右孩子為2i+1由性質(zhì)由性質(zhì)1和定義,可知除第和定義,可知除第h層外,其余各層都是滿的,所以:層外,其余各層都是滿的,所以:1+k+k2+.+kh-2=(kh-1-1)/(k-1),則最多有:,則最多有: (kh-1-1)/(k-1)+kh-1=(kh-1)/(k-1);最少有:最少有:(kh-1-1)/(k-1)+1課后作業(yè)課后作業(yè)P38:6.5P39:6.6(要求:寫出推導(dǎo)

20、過程要求:寫出推導(dǎo)過程)6.2.3 二叉樹的存儲結(jié)構(gòu)二叉樹的存儲結(jié)構(gòu)n順序存儲結(jié)構(gòu):順序存儲結(jié)構(gòu):#define MAX_TREE_SIZE 100 / 二叉樹的最大結(jié)點數(shù)二叉樹的最大結(jié)點數(shù)typedef TElemType SqBiTreeMAX_TREE_SIZE; / 0號單元存儲根結(jié)點號單元存儲根結(jié)點SqBiTree bt;特點:特點:n一組地址連續(xù)的存儲單元存儲各結(jié)點一組地址連續(xù)的存儲單元存儲各結(jié)點(定義一個一維定義一個一維數(shù)組數(shù)組);n自根而下、自左而右存儲結(jié)點;自根而下、自左而右存儲結(jié)點;n按按完全二叉樹完全二叉樹上的上的結(jié)點位置結(jié)點位置進行編號和存儲。進行編號和存儲。例如:例如

21、:ABCDEF A B D C E F 0 1 2 3 4 5 6 7 8 9 10 11 12 131401326在最壞的情況下,一個深度為在最壞的情況下,一個深度為k且只有且只有k個結(jié)點的單支樹個結(jié)點的單支樹(樹中不存在度為樹中不存在度為2的的結(jié)點結(jié)點)卻需要卻需要2k-1的一維數(shù)組。的一維數(shù)組。缺點:空間利用率太低!缺點:空間利用率太低!n鏈?zhǔn)酱鎯Y(jié)構(gòu):鏈?zhǔn)酱鎯Y(jié)構(gòu):二叉鏈表:二叉鏈表:ADEBCF rootlchild data rchild結(jié)點結(jié)構(gòu)結(jié)點結(jié)構(gòu): :C語言的類型描述:語言的類型描述:typedef struct BiTNode / 結(jié)點結(jié)構(gòu)結(jié)點結(jié)構(gòu) TElemType d

22、ata; struct BiTNode *lchild, *rchild; / 左右孩子指針左右孩子指針 BiTNode, *BiTree;三叉鏈表:三叉鏈表:ADEBCF root parent lchild data rchild結(jié)點結(jié)構(gòu)結(jié)點結(jié)構(gòu): :typedef struct TriTNode / 結(jié)點結(jié)構(gòu)結(jié)點結(jié)構(gòu) TElemType data; struct TriTNode *lchild, *rchild; / 左右孩子指針左右孩子指針 struct TriTNode *parent; /雙親指針雙親指針 TriTNode, *TriTree;6.3.1 遍歷二叉樹遍歷二叉樹n問

23、題的提出:問題的提出: 順著某一條搜索路徑順著某一條搜索路徑巡訪巡訪二叉樹中的結(jié)點,使二叉樹中的結(jié)點,使得每個結(jié)點得每個結(jié)點均被訪問一次均被訪問一次,而且,而且僅被訪問一次僅被訪問一次。注意:此處注意:此處“訪問訪問”的含義可以很廣,如:輸出的含義可以很廣,如:輸出結(jié)點的信息等。結(jié)點的信息等。 “遍歷遍歷”是任何類型均有的操作,對線性結(jié)構(gòu)而言,是任何類型均有的操作,對線性結(jié)構(gòu)而言,只有一條搜索路徑只有一條搜索路徑( (因為每個結(jié)點均只有一個后繼因為每個結(jié)點均只有一個后繼) ),故不需要另加討論。而二叉樹是非線性結(jié)構(gòu),每個結(jié)故不需要另加討論。而二叉樹是非線性結(jié)構(gòu),每個結(jié)點有兩個后繼,則存在如何遍

24、歷即按什么樣的搜索路點有兩個后繼,則存在如何遍歷即按什么樣的搜索路徑遍歷的問題。徑遍歷的問題。6.3 遍歷二叉樹和線索二叉樹遍歷二叉樹和線索二叉樹n三條搜索路徑:三條搜索路徑:先上后下先上后下的按層次遍歷;的按層次遍歷;先左先左(子樹子樹)后右后右(子樹子樹)的遍歷;的遍歷;先右先右(子樹子樹)后左后左(子樹子樹)的遍歷。的遍歷。n先左后右的遍歷算法:先左后右的遍歷算法:先先(根根)序的遍歷算法序的遍歷算法中中(根根)序的遍歷算法序的遍歷算法后后(根根)序的遍歷算法序的遍歷算法根根左左子樹子樹右右子樹子樹先先(根根)序的遍歷算法:序的遍歷算法:若二叉樹為空樹,則空操作;否則,若二叉樹為空樹,則

25、空操作;否則, 訪問根結(jié)點;訪問根結(jié)點; 先序遍歷左子樹;先序遍歷左子樹; 先序遍歷右子樹。先序遍歷右子樹。中中(根根)序的遍歷算法:序的遍歷算法:若二叉樹為空樹,則空操作;否則,若二叉樹為空樹,則空操作;否則, 中序遍歷左子樹;中序遍歷左子樹; 訪問根結(jié)點;訪問根結(jié)點; 中序遍歷右子樹。中序遍歷右子樹。后后(根根)序的遍歷算法:序的遍歷算法:若二叉樹為空樹,則空操作;否則,若二叉樹為空樹,則空操作;否則, 后序遍歷左子樹;后序遍歷左子樹; 后序遍歷右子樹;后序遍歷右子樹; 訪問根結(jié)點。訪問根結(jié)點。例如:例如:ABCDEFGHK先序序列:先序序列:中序序列:中序序列:后序序列:后序序列:A B

26、 C D E F G H KB D C A E H G K FD C B H K G F E AFn算法的遞歸實現(xiàn):算法的遞歸實現(xiàn):void Preorder (BiTree T, void ( *visit)(TElemType e) / 先序遍歷二叉樹先序遍歷二叉樹 if (T) visit(T-data); / 訪問結(jié)點訪問結(jié)點 Preorder(T-lchild, visit); / 遍歷左子樹遍歷左子樹 Preorder(T-rchild, visit); / 遍歷右子樹遍歷右子樹 寫法比較:寫法比較:nint ( *visit)(TElemType &e)的含義:的含義:

27、visit是指針,指向是指針,指向int類型的函數(shù)類型的函數(shù)nint *visit(TElemType &e)的含義:的含義: visit是函數(shù),其返回值為指向是函數(shù),其返回值為指向int的指針的指針最簡單的最簡單的visit函數(shù)是:函數(shù)是:Void PrintElement(TElemType e) Printf(e);例:對應(yīng)表達式例:對應(yīng)表達式 a+b*(c-d)-e/fabcde-+/f-中序遍歷中序遍歷此二叉樹,可得到此二叉樹此二叉樹,可得到此二叉樹的中序序列為的中序序列為a+b*c-d-e/f (表達式的表達式的中綴中綴表示表示)若若先序遍歷先序遍歷二叉樹,按訪問結(jié)點的先后

28、二叉樹,按訪問結(jié)點的先后次序?qū)⒔Y(jié)點排列起來,可得到二叉樹的次序?qū)⒔Y(jié)點排列起來,可得到二叉樹的先序序列為先序序列為 -+a*b-cd/ef (表達式的表達式的前綴前綴表示表示波蘭式波蘭式)后序遍歷后序遍歷此二叉樹,可得到此二叉樹的后序序此二叉樹,可得到此二叉樹的后序序列為列為abcd-*+ef/- (表達式的表達式的后綴后綴表示表示逆波蘭式逆波蘭式)n遍歷的遞歸執(zhí)行過程:遍歷的遞歸執(zhí)行過程:例如:表達式例如:表達式a*b-c的二叉樹如下的二叉樹如下a-b*c-*abc-*abc-cb*aab*c-12先序序列:先序序列:-*abc中序序列:中序序列:a*b-c后序序列:后序序列:ab*c-n中序

29、遍歷的非遞歸算法:中序遍歷的非遞歸算法:BiTNode *GoFarLeft(BiTree T, Stack *S) if (!T ) return NULL; while (T-lchild ) Push(S, T); T = T-lchild; return T;-*abcab*c-12TTlchildTlchildlchildTlchildlchildlchildTtoptoptoptoptopTlchildlchildrchildTlchildrchildTlchildrchildlchildTlchildrchildrchildvoid Inorder_I(BiTree T, voi

30、d (*visit) (TelemType& e) Stack *S; t = GoFarLeft(T, S); / 找到最左下的結(jié)點找到最左下的結(jié)點 while(t) visit(t-data); if (t-rchild) t = GoFarLeft(t-rchild, S); else if ( !StackEmpty(S ) / 棧不空時退棧棧不空時退棧 t = Pop(S); else t = NULL; / ??毡砻鞅闅v結(jié)束??毡砻鞅闅v結(jié)束 / while/ Inorder_I n遍歷算法的應(yīng)用舉例:遍歷算法的應(yīng)用舉例:統(tǒng)計二叉樹中葉子結(jié)點的個數(shù)統(tǒng)計二叉樹中葉子結(jié)點的個數(shù)n

31、算法基本思想算法基本思想: 先序先序(或中序或后序或中序或后序)遍歷二叉樹,在遍歷過程中查找葉遍歷二叉樹,在遍歷過程中查找葉子結(jié)點,并計數(shù)。由此,需在遍歷算法中:子結(jié)點,并計數(shù)。由此,需在遍歷算法中:增添增添一個一個“計數(shù)計數(shù)”的參數(shù)的參數(shù);將算法中將算法中“訪問結(jié)點訪問結(jié)點”的的操作改為操作改為:若是:若是葉子,則計數(shù)葉子,則計數(shù)器增器增1。void CountLeaf (BiTree T, int& count) if ( T ) if (!T-lchild)& (!T-rchild) count+; / 對葉子結(jié)點計數(shù)對葉子結(jié)點計數(shù) CountLeaf( T-lchild

32、, count); /統(tǒng)計左子樹葉子結(jié)點統(tǒng)計左子樹葉子結(jié)點 CountLeaf( T-rchild, count); /統(tǒng)計右子樹葉子結(jié)點統(tǒng)計右子樹葉子結(jié)點 / if / CountLeaf求二叉樹的深度求二叉樹的深度(后序遍歷后序遍歷)分析分析:二叉樹的深度:二叉樹的深度h和它的左、右子樹深度之間的和它的左、右子樹深度之間的關(guān)系?關(guān)系?n算法基本思想算法基本思想:先先分別分別求得左、右子樹求得左、右子樹的深度;的深度;算法中算法中“訪問結(jié)點訪問結(jié)點”的的操作為操作為:求得左、右子樹深度的:求得左、右子樹深度的最大值,然后加最大值,然后加 1 。int Depth (BiTree T ) /

33、返回二叉樹的深度返回二叉樹的深度 if ( !T ) depthval = 0; else depthLeft = Depth( T-lchild ); /求左子樹深度求左子樹深度 depthRight= Depth( T-rchild ); /求右子樹深度求右子樹深度 depthval = 1 + (depthLeft depthRight ? depthLeft : depthRight); return depthval;h=maxhl, hr+1復(fù)制二叉樹復(fù)制二叉樹(后序遍歷后序遍歷):n其基本操作為:生成一個結(jié)點其基本操作為:生成一個結(jié)點根元素根元素T左子樹左子樹右子樹右子樹根元素根

34、元素NEWT左子樹左子樹右子樹右子樹左子樹左子樹右子樹右子樹n算法思想算法思想:復(fù)制左、右子樹;復(fù)制左、右子樹;“訪問結(jié)點訪問結(jié)點”的操作為:生成一個結(jié)點。的操作為:生成一個結(jié)點。n生成一個二叉樹的結(jié)點生成一個二叉樹的結(jié)點(其數(shù)據(jù)域為其數(shù)據(jù)域為item,左指針域為左指針域為lptr,右指針域為右指針域為rptr)BiTNode *GetTreeNode(TElemType item, BiTNode *lptr , BiTNode *rptr ) if (!(T = (BiTNode*)malloc(sizeof(BiTNode) exit(1); T- data = item; T- lch

35、ild = lptr; T- rchild = rptr; return T;n復(fù)制:復(fù)制:BiTNode *CopyTree(BiTNode *T) if (!T ) return NULL; if (T-lchild ) newlptr = CopyTree(T-lchild); /復(fù)制左子樹復(fù)制左子樹 else newlptr = NULL; if (T-rchild ) newrptr = CopyTree(T-rchild); /復(fù)制右子樹復(fù)制右子樹 else newrptr = NULL; newT = GetTreeNode(T-data, newlptr, newrptr);

36、return newT; / CopyTree例如:下列二叉樹的復(fù)制過程如下例如:下列二叉樹的復(fù)制過程如下ABCDEFGHK D C B H K G F E AnewTn建立二叉樹的存儲結(jié)構(gòu):建立二叉樹的存儲結(jié)構(gòu):基本要點:基本要點: n以以“遍歷遍歷”為基本出發(fā)點為基本出發(fā)點n不同的遍歷方法相應(yīng)地有不同的建立算法代碼不同的遍歷方法相應(yīng)地有不同的建立算法代碼以以字符串字符串的形式的形式“根左子樹右子樹根左子樹右子樹”定義一定義一棵二叉樹棵二叉樹例如:例如:ABCD以空白字符以空白字符“ ”表示表示A(B( ,C( , ),D( , )空樹空樹只含一個根結(jié)點的二叉樹只含一個根結(jié)點的二叉樹A以字符

37、串以字符串“A ”表示表示以下列字符串表示以下列字符串表示Status CreateBiTree(BiTree &T) /先序次序輸入結(jié)點先序次序輸入結(jié)點 scanf(&ch); if (ch= ) T = NULL; /第一個字符為空白字符第一個字符為空白字符 else if (!(T = (BiTNode *)malloc(sizeof(BiTNode) exit(OVERFLOW); T-data = ch; / 生成根結(jié)點生成根結(jié)點 CreateBiTree(T-lchild); / 構(gòu)造左子樹構(gòu)造左子樹 CreateBiTree(T-rchild); / 構(gòu)造右子樹構(gòu)

38、造右子樹 return OK; / CreateBiTree上述算法的執(zhí)行過程:上述算法的執(zhí)行過程:A B C D A BCDATBCD由二叉樹的由二叉樹的先序和中序先序和中序序列建樹:序列建樹:n僅知僅知二叉樹的二叉樹的先序序列先序序列“abcdefg” ,不能不能唯一確定唯一確定一棵二叉樹。一棵二叉樹。n如果同時已知二叉樹的中序序列如果同時已知二叉樹的中序序列“cbdaegf”,則會,則會如何?如何?二叉樹的二叉樹的先序先序序列序列二叉樹的二叉樹的中序中序序列序列左子樹左子樹右子樹右子樹根根左子樹左子樹右子樹右子樹根根abcdefgcbdaegf例如:例如:a b c d e f gc b

39、 d a e g faab bccddeeffggabcdefg先序序列先序序列中序序列中序序列課后作業(yè)課后作業(yè)1. P41:6.286.3.2 線索二叉樹線索二叉樹n何謂線索二叉樹?何謂線索二叉樹?遍歷二叉樹的結(jié)果是,求得結(jié)點的一個線性序列。遍歷二叉樹的結(jié)果是,求得結(jié)點的一個線性序列。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“前驅(qū)前驅(qū)”和和“后繼后繼”的信息是在遍歷的過程中的信息是在遍歷的過程中動態(tài)動態(tài)得到的,不同的遍歷算法,確定的得到的,不同

40、的遍歷算法,確定的“前驅(qū)前驅(qū)”和和“后繼后繼”是不同的!是不同的!保保 存存?指向該指向該線性序列中線性序列中的的“前驅(qū)前驅(qū)”和和 “后繼后繼” 的指針,的指針,稱作稱作“線索線索”。A B C D E F G H K D C B E 包含包含“線索線索”的存儲結(jié)構(gòu),的存儲結(jié)構(gòu),稱作稱作“線索鏈表線索鏈表”。與其相應(yīng)的二叉樹,稱作與其相應(yīng)的二叉樹,稱作“線索二叉樹線索二叉樹”。n對線索鏈表中結(jié)點的約定:對線索鏈表中結(jié)點的約定: 在二叉鏈表的結(jié)點中在二叉鏈表的結(jié)點中增加兩個標(biāo)志域增加兩個標(biāo)志域,并作如,并作如下規(guī)定:下規(guī)定:若該結(jié)點的若該結(jié)點的左子樹不空左子樹不空, 則則lchild域的指針指向

41、其左子樹,且左標(biāo)志域的值域的指針指向其左子樹,且左標(biāo)志域的值為為“指針指針 Link”;否則,;否則,lchild域的指針指向其域的指針指向其“前驅(qū)前驅(qū)”,且左標(biāo)志的值為,且左標(biāo)志的值為“線索線索 Thread” 。若該結(jié)點的若該結(jié)點的右子樹不空右子樹不空, 則則rchild域的指針指向其右子樹,且右標(biāo)志域的值域的指針指向其右子樹,且右標(biāo)志域的值為為 “指針指針 Link”;否則,;否則,rchild域的指針指向其域的指針指向其“后繼后繼”,且右標(biāo)志的值為,且右標(biāo)志的值為“線索線索 Thread”。 n線索鏈表的存儲描述:線索鏈表的存儲描述:typedef enum Link, Thread

42、PointerThr; / Link=0:指針,指針,Thread=1:線索線索typedef struct BiThrNod TElemType data; struct BiThrNode *lchild, *rchild; / 左、右指針左、右指針 PointerThr LTag, RTag; / 左、右標(biāo)志左、右標(biāo)志 BiThrNode, *BiThrTree;lchild LTag data RTag rchildp對二叉樹對二叉樹以某種次序遍歷以某種次序遍歷使其變?yōu)榫€索二叉樹的過程使其變?yōu)榫€索二叉樹的過程稱為稱為線索化線索化。思考:一棵二叉樹的線索二叉樹是唯一的嗎?思考:一棵二叉樹

43、的線索二叉樹是唯一的嗎?二叉線索鏈表二叉線索鏈表n二叉線索鏈表的遍歷:二叉線索鏈表的遍歷: 添加了遍歷中得到的添加了遍歷中得到的“前驅(qū)前驅(qū)”和和“后繼后繼”的信的信息,從而簡化了遍歷的算法。息,從而簡化了遍歷的算法。for ( p = firstNode(T); p; p = Succ(p) ) Visit (p);例如:對中序線索化鏈表的遍歷算法。例如:對中序線索化鏈表的遍歷算法。中序遍歷的第一個結(jié)點中序遍歷的第一個結(jié)點 ? 左子樹上處于左子樹上處于“最左下最左下”(沒有左子樹沒有左子樹)的結(jié)點。的結(jié)點。在中序線索化鏈表中結(jié)點的后繼在中序線索化鏈表中結(jié)點的后繼 ?n若結(jié)點無右子樹若結(jié)點無右子

44、樹, 則則右鏈域所指右鏈域所指結(jié)點即結(jié)點即為其后繼為其后繼;n否則對其否則對其右子樹右子樹進行中序遍歷,進行中序遍歷,訪問的第一個結(jié)點訪問的第一個結(jié)點。void InOrderTraverse_Thr(BiThrTree T, void (*Visit)(TElemType e) p = T-lchild; / T是是頭結(jié)點指針頭結(jié)點指針,p指向根結(jié)點指向根結(jié)點 while (p != T) / 空樹或遍歷結(jié)束時,空樹或遍歷結(jié)束時,p=T while (p-LTag=Link) p = p-lchild; / 找到序列中第一個結(jié)點找到序列中第一個結(jié)點 if (!Visit(p-data) re

45、turn ERROR;/訪問左子樹為空的結(jié)點訪問左子樹為空的結(jié)點 while (p-RTag=Thread & p-rchild!=T) p = p-rchild; Visit(p-data); / 訪問后繼結(jié)點訪問后繼結(jié)點 p = p-rchild; / p進入其右子樹根進入其右子樹根 / InOrderTraverse_Thr例如例如: 表達式的中序線索化鏈表的遍歷。表達式的中序線索化鏈表的遍歷。abcde-+/f-NILNIL010000110000111111001111-+abcd-*ef/thrtbtpa + b * c - d - e / fppp判斷標(biāo)志域,然后沿著指針判斷標(biāo)志域,然后沿著指針/ /線索線索訪問后繼結(jié)點!訪問后繼結(jié)點!n如何建立線索鏈表?如何建立線索鏈表?在中序遍歷過程

溫馨提示

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

評論

0/150

提交評論