《數(shù)據(jù)結(jié)構(gòu)》課件第6章 樹(shù)和二叉樹(shù)_第1頁(yè)
《數(shù)據(jù)結(jié)構(gòu)》課件第6章 樹(shù)和二叉樹(shù)_第2頁(yè)
《數(shù)據(jù)結(jié)構(gòu)》課件第6章 樹(shù)和二叉樹(shù)_第3頁(yè)
《數(shù)據(jù)結(jié)構(gòu)》課件第6章 樹(shù)和二叉樹(shù)_第4頁(yè)
《數(shù)據(jù)結(jié)構(gòu)》課件第6章 樹(shù)和二叉樹(shù)_第5頁(yè)
已閱讀5頁(yè),還剩54頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、第6章 樹(shù)和二叉樹(shù)學(xué)習(xí)要點(diǎn): 熟練掌握二叉樹(shù)的結(jié)構(gòu)特性熟悉二叉樹(shù)的各種存儲(chǔ)結(jié)構(gòu)特點(diǎn)及使用范圍熟練掌握各種遍歷策略的遞歸和非遞歸算法,靈活運(yùn)用遍歷算法實(shí)現(xiàn)二叉樹(shù)的其他操作熟練掌握二叉樹(shù)的線(xiàn)索化過(guò)程以及在中序線(xiàn)索化樹(shù)上找給定結(jié)點(diǎn)的前驅(qū)和后繼的方法掌握樹(shù)和森林與二叉樹(shù)的轉(zhuǎn)換方法學(xué)會(huì)編寫(xiě)實(shí)現(xiàn)樹(shù)的各種操作的算法了解最優(yōu)樹(shù)的特性,掌握建立最優(yōu)樹(shù)和哈夫曼編碼的方法6.1 樹(shù)的定義和基本術(shù)語(yǔ)6.1.1 樹(shù)的定義樹(shù)型結(jié)構(gòu):非線(xiàn)性結(jié)構(gòu):至少存在一個(gè)數(shù)據(jù)元素有兩個(gè)或兩個(gè)以上的直接前驅(qū)(或直接后繼)元素的數(shù)據(jù)結(jié)構(gòu)。用于描述層次結(jié)構(gòu)的關(guān)系:人類(lèi)的族譜、操作系統(tǒng)的文件系統(tǒng)、Internet中的DNS(域名系統(tǒng))等分等級(jí)的

2、分類(lèi)方案均可用層次結(jié)構(gòu)來(lái)表示,可由此導(dǎo)出樹(shù)型結(jié)構(gòu)。樹(shù)的定義: 是n(n0)個(gè)結(jié)點(diǎn)的有限集合T,對(duì)于任意一棵非空樹(shù),它滿(mǎn)足:有且僅有一個(gè)特定的稱(chēng)為根(root)的結(jié)點(diǎn);當(dāng)n1時(shí),其余結(jié)點(diǎn)可分為m(m0)個(gè)互不相交的有限集T1,T2,.,Tm,其中每個(gè)集合本身又是一棵樹(shù),稱(chēng)為根的子樹(shù)。上述樹(shù)的定義是一個(gè)遞歸定義。例如:ABCDEFGHIJMKLA樹(shù)的類(lèi)型定義:ADT Tree 數(shù)據(jù)對(duì)象:D是具有相同特性的數(shù)據(jù)元素的集合。 數(shù)據(jù)關(guān)系:若D為空集,則稱(chēng)為空樹(shù);否則: (1) 在D中存在唯一的稱(chēng)為根的數(shù)據(jù)元素root, (2) 當(dāng)n1時(shí),其余結(jié)點(diǎn)可分為m (m0)個(gè)互不相交的有限集T1, T2, , T

3、m, 其中每一棵子集本身又是一棵符合本定義的樹(shù),稱(chēng)為根root的子樹(shù)。 基本操作:查找類(lèi)插入 刪除 ADT Tree查找類(lèi):Root(T) / 求樹(shù)的根結(jié)點(diǎn) Value(T, cur_e) / 求當(dāng)前結(jié)點(diǎn)的元素值Parent(T, cur_e) / 求當(dāng)前結(jié)點(diǎn)的雙親結(jié)點(diǎn)LeftChild(T, cur_e) / 求當(dāng)前結(jié)點(diǎn)的最左孩子RightSibling(T, cur_e) / 求當(dāng)前結(jié)點(diǎn)的右兄弟TreeEmpty(T) / 判定樹(shù)是否為空樹(shù)TreeDepth(T) / 求樹(shù)的深度TraverseTree( T, Visit() ) / 遍歷插入:InitTree(&T) / 初始化置空樹(shù)C

4、reateTree(&T, definition) / 按定義構(gòu)造Assign(T, cur_e, value) / 給當(dāng)前結(jié)點(diǎn)賦值InsertChild(&T, &p, i, c) / 將以c為根的樹(shù)插入為結(jié) /點(diǎn)p的第i棵子樹(shù)刪除:ClearTree(&T) / 將樹(shù)清空DestroyTree(&T) / 銷(xiāo)毀樹(shù)的結(jié)構(gòu)DeleteChild(&T, &p, i) / 刪除結(jié)點(diǎn)p的第i棵子例如:ABCDEFGHIJMKL(A( B(E, F(K, L), C(G), D(H, I, J(M) )T1T3T2樹(shù)根T1T2T36.1.2 基本術(shù)語(yǔ)結(jié)點(diǎn):包含一個(gè)數(shù)據(jù)元素及若干指向其子樹(shù)的分支。結(jié)點(diǎn)

5、的度:結(jié)點(diǎn)擁有的子樹(shù)數(shù)。如圖: A的度為3, C的度為1, E的度為0。葉子(或終端)結(jié)點(diǎn):度為零的結(jié)點(diǎn)。分支(或非終端)結(jié)點(diǎn):度大于零的結(jié)點(diǎn)。ABCDEFGHIJMKL樹(shù)的度:樹(shù)中所有結(jié)點(diǎn)的度的最大值。結(jié)點(diǎn)的子樹(shù)的根稱(chēng)為該結(jié)點(diǎn)的孩子(child) 。相應(yīng)的,該結(jié)點(diǎn)稱(chēng)為孩子的雙親(parent)。如圖所示,樹(shù)的度為3;D為A的子樹(shù)T3的根,則D是A的孩子,而A則是D的雙親。同一個(gè)雙親的孩子之間互 稱(chēng)兄弟。如圖所示中,H、I、J互稱(chēng)為兄弟。ABCDEFGHIJMKLE、G、H互稱(chēng)兄弟?雙親在同一層的結(jié)點(diǎn)互為堂兄弟。結(jié)點(diǎn)的層次:根結(jié)點(diǎn)的層次為1,第l層的結(jié)點(diǎn)的子樹(shù)的根結(jié)點(diǎn)的層次為l+1。樹(shù)的深度:

6、樹(shù)中葉子結(jié)點(diǎn)所在的最大層次。森林:是m(m0)棵互不相交的樹(shù)的集合。任何一棵非空樹(shù)是一個(gè)二元組Tree = (root,F(xiàn))其中: root 被稱(chēng)為根結(jié)點(diǎn) F 被稱(chēng)為子樹(shù)森林ArootBCDEFGHIJMKLF有序樹(shù):子樹(shù)之間存在確定的次序關(guān)系。(樹(shù)中結(jié)點(diǎn)的各子樹(shù)從左到右是有次序的,即不能互換)。無(wú)序樹(shù):子樹(shù)之間不存在確定的次序關(guān)系。樹(shù)型結(jié)構(gòu)和線(xiàn)性結(jié)構(gòu)的特點(diǎn):線(xiàn)性結(jié)構(gòu)樹(shù)型結(jié)構(gòu)第一個(gè)數(shù)據(jù)元素 (無(wú)前驅(qū)) 根結(jié)點(diǎn) (無(wú)前驅(qū))最后一個(gè)數(shù)據(jù)元素 (無(wú)后繼)多個(gè)葉子結(jié)點(diǎn) (無(wú)后繼)其它數(shù)據(jù)元素(一個(gè)前驅(qū)、 一個(gè)后繼)其它數(shù)據(jù)元素(一個(gè)前驅(qū)、 多個(gè)后繼)6.2.1 二叉樹(shù)的定義定義:是n(n=0)個(gè)結(jié)點(diǎn)的

7、有限集合,它或?yàn)榭諛?shù)(n=0),或由一個(gè)根結(jié)點(diǎn)和至多兩棵稱(chēng)為根的左子樹(shù)和右子樹(shù)的互不相交的二叉樹(shù)組成。注:二叉樹(shù)中不存在度大于2的結(jié)點(diǎn),并且二叉樹(shù)的子樹(shù)有左子樹(shù)和右子樹(shù)之分。6.2 二叉樹(shù)ABCDEFGHK根結(jié)點(diǎn)左子樹(shù)右子樹(shù)二叉樹(shù)的五種基本形態(tài):N空樹(shù)只含根結(jié)點(diǎn)NNNLRR右子樹(shù)為空樹(shù)L左子樹(shù)為空樹(shù)左右子樹(shù)均不為空樹(shù)二叉樹(shù)的抽象數(shù)據(jù)類(lèi)型定義:ADT BinaryTree 數(shù)據(jù)對(duì)象:D是具有相同特性的數(shù)據(jù)元素的集合。 數(shù)據(jù)關(guān)系:若D為空集,則稱(chēng)為空樹(shù);否則: (1) 在D中存在唯一的稱(chēng)為根的數(shù)據(jù)元素root, . 基本操作:查找類(lèi)插入 刪除ADT BinaryTree 詳細(xì)說(shuō)明見(jiàn)教材P121P1

8、236.2.2 二叉樹(shù)的性質(zhì)性質(zhì)1 :在二叉樹(shù)的第 i 層上至多有2i-1 個(gè)結(jié)點(diǎn)(i1)。證明:(歸納法)歸納基:i = 1 層時(shí),只有一個(gè)根結(jié)點(diǎn): 2i-1 = 20 = 1,命題成立。歸納假設(shè):假設(shè)對(duì)所有的 j,1 j i,命題成立。即第j層上至多有2j-1個(gè)結(jié)點(diǎn)。歸納證明:j=i時(shí),命題成立。 二叉樹(shù)上每個(gè)結(jié)點(diǎn)至多有兩棵子樹(shù),且由歸納假設(shè)有:第i-1層上至多有2i-2個(gè)結(jié)點(diǎn) 第 j=i 層的結(jié)點(diǎn)數(shù)至多 = 2i-2 2 = 2i-1 。命題成立(證畢)性質(zhì)2:深度為 k 的二叉樹(shù)上至多含 2k-1 個(gè)結(jié)點(diǎn)(k1)。證明:基于性質(zhì)1,深度為 k 的二叉樹(shù)上的結(jié)點(diǎn)數(shù)至多為:20+21+ +

9、2k-1 = 2k-1 。性質(zhì)3:對(duì)任何一棵二叉樹(shù),若它含有n0 個(gè)葉子結(jié)點(diǎn)、n2 個(gè)度為2的結(jié)點(diǎn),則必存在關(guān)系式:n0 = n2+1。證明:設(shè)二叉樹(shù)上結(jié)點(diǎn)總數(shù) n = n0 + n1 + n2, 二叉樹(shù)上分支總數(shù) b = n1+2n2, 而 b = n-1 = n0 + n1 + n2 1 由, n0 = n2 + 1 。除根結(jié)點(diǎn)外,其余結(jié)點(diǎn)都有一個(gè)分支進(jìn)入,設(shè)b為分支總數(shù),則n=b+1。兩類(lèi)特殊的二叉樹(shù):滿(mǎn)二叉樹(shù):指的是深度為k且含有2k-1個(gè)結(jié)點(diǎn)的二叉樹(shù)。完全二叉樹(shù):樹(shù)中所含的 n 個(gè)結(jié)點(diǎn)和滿(mǎn)二叉樹(shù)中編號(hào)為 1 至 n 的結(jié)點(diǎn)一一對(duì)應(yīng)。123456789101112131415abcde

10、fghij特點(diǎn):是每一層上的結(jié)點(diǎn)數(shù)都是最大結(jié)點(diǎn)數(shù)。特點(diǎn):葉子結(jié)點(diǎn)只可能在層次最大的兩層出現(xiàn);對(duì)任一結(jié)點(diǎn),若其右分支下的子孫的最大層次為l,則其左分支下的子孫的最大層次為l或l+1。完全二叉樹(shù)的性質(zhì):性質(zhì)4:具有n個(gè)結(jié)點(diǎn)的完全二叉樹(shù)的深度為 log2n +1。證明:設(shè)完全二叉樹(shù)的深度為k,則根據(jù)性質(zhì)2(深度為k的二叉樹(shù)至多有2k-1個(gè)結(jié)點(diǎn)) 得 2k-1-1 n 2k 1,或: 2k-1 n 2k 即 k-1 log2 n n,則該結(jié)點(diǎn)無(wú)左孩子,否則,編號(hào)為 2i 的結(jié)點(diǎn)為其左孩子結(jié)點(diǎn);(3)若 2i+1n,則該結(jié)點(diǎn)無(wú)右孩子結(jié)點(diǎn),否則,編號(hào)為2i+1 的結(jié)點(diǎn)為其右孩子結(jié)點(diǎn)。i/2 i 2i 2i

11、+1 i+1 2i+2 2i+3 i+1 2i+2 2i+3 i2i2i+1 .性質(zhì)練習(xí):1. 一棵二叉樹(shù)在其第五層中有17個(gè)結(jié)點(diǎn),可不可能?2. 二叉樹(shù)的根結(jié)點(diǎn)屬于第0層還是屬于第1層?3. 已知一棵二叉樹(shù)有20個(gè)結(jié)點(diǎn),其中6個(gè)結(jié)點(diǎn)為葉子,則該樹(shù)中度為2的結(jié)點(diǎn)數(shù)為 ?度為0的結(jié)點(diǎn)為 ?4. 已知一棵完全二叉樹(shù)中編號(hào)為101的結(jié)點(diǎn)有LC和RC結(jié)點(diǎn),則其LC結(jié)點(diǎn)編號(hào)為 ,RC結(jié)點(diǎn)編號(hào)為 ?5. 一棵深度為h的完全k叉樹(shù),如果按層次自頂向下、同一層自左向右、順序從1開(kāi)始對(duì)全部結(jié)點(diǎn)進(jìn)行編號(hào),試問(wèn):該樹(shù)上最多有多少個(gè)結(jié)點(diǎn)?最少有多少個(gè)結(jié)點(diǎn)?第i層上至多有2i-1個(gè)結(jié)點(diǎn),則25-1=16。所以,不可能。

12、第1層56由性質(zhì)3:n0=n2+1,則n2=n0-1=6-1=5。202203由性質(zhì)5,可知左孩子為2i,右孩子為2i+1由性質(zhì)1和定義,可知除第h層外,其余各層都是滿(mǎn)的,所以: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è)P38:6.5P39:6.6(要求:寫(xiě)出推導(dǎo)過(guò)程)6.2.3 二叉樹(shù)的存儲(chǔ)結(jié)構(gòu)順序存儲(chǔ)結(jié)構(gòu):#define MAX_TREE_SIZE 100 / 二叉樹(shù)的最大結(jié)點(diǎn)數(shù)typedef TElemType SqBiTreeMAX_TREE_S

13、IZE; / 0號(hào)單元存儲(chǔ)根結(jié)點(diǎn)SqBiTree bt;特點(diǎn):一組地址連續(xù)的存儲(chǔ)單元存儲(chǔ)各結(jié)點(diǎn)(定義一個(gè)一維數(shù)組);自根而下、自左而右存儲(chǔ)結(jié)點(diǎn);按完全二叉樹(shù)上的結(jié)點(diǎn)位置進(jìn)行編號(hào)和存儲(chǔ)。例如:ABCDEF A B D C E F 0 1 2 3 4 5 6 7 8 9 10 11 12 131401326在最壞的情況下,一個(gè)深度為k且只有k個(gè)結(jié)點(diǎn)的單支樹(shù)(樹(shù)中不存在度為2的結(jié)點(diǎn))卻需要2k-1的一維數(shù)組。缺點(diǎn):空間利用率太低!鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu):二叉鏈表:ADEBCFrootlchild data rchild結(jié)點(diǎn)結(jié)構(gòu):C語(yǔ)言的類(lèi)型描述:typedef struct BiTNode / 結(jié)點(diǎn)結(jié)構(gòu) TE

14、lemType data; struct BiTNode *lchild, *rchild; / 左右孩子指針 BiTNode, *BiTree;三叉鏈表:ADEBCFrootparent lchild data rchild結(jié)點(diǎn)結(jié)構(gòu):typedef struct TriTNode / 結(jié)點(diǎn)結(jié)構(gòu) TElemType data; struct TriTNode *lchild, *rchild; / 左右孩子指針 struct TriTNode *parent; /雙親指針 TriTNode, *TriTree;6.3.1 遍歷二叉樹(shù)問(wèn)題的提出: 順著某一條搜索路徑巡訪(fǎng)二叉樹(shù)中的結(jié)點(diǎn),使得每個(gè)結(jié)

15、點(diǎn)均被訪(fǎng)問(wèn)一次,而且僅被訪(fǎng)問(wèn)一次。注意:此處“訪(fǎng)問(wèn)”的含義可以很廣,如:輸出結(jié)點(diǎn)的信息等。 “遍歷”是任何類(lèi)型均有的操作,對(duì)線(xiàn)性結(jié)構(gòu)而言,只有一條搜索路徑(因?yàn)槊總€(gè)結(jié)點(diǎn)均只有一個(gè)后繼),故不需要另加討論。而二叉樹(shù)是非線(xiàn)性結(jié)構(gòu),每個(gè)結(jié)點(diǎn)有兩個(gè)后繼,則存在如何遍歷即按什么樣的搜索路徑遍歷的問(wèn)題。6.3 遍歷二叉樹(shù)和線(xiàn)索二叉樹(shù)三條搜索路徑:先上后下的按層次遍歷;先左(子樹(shù))后右(子樹(shù))的遍歷;先右(子樹(shù))后左(子樹(shù))的遍歷。先左后右的遍歷算法:先(根)序的遍歷算法中(根)序的遍歷算法后(根)序的遍歷算法根左子樹(shù)右子樹(shù)先(根)序的遍歷算法:若二叉樹(shù)為空樹(shù),則空操作;否則, 訪(fǎng)問(wèn)根結(jié)點(diǎn); 先序遍歷左子樹(shù)

16、; 先序遍歷右子樹(shù)。中(根)序的遍歷算法:若二叉樹(shù)為空樹(shù),則空操作;否則, 中序遍歷左子樹(shù); 訪(fǎng)問(wèn)根結(jié)點(diǎn); 中序遍歷右子樹(shù)。后(根)序的遍歷算法:若二叉樹(shù)為空樹(shù),則空操作;否則, 后序遍歷左子樹(shù); 后序遍歷右子樹(shù); 訪(fǎng)問(wèn)根結(jié)點(diǎn)。例如: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 AF算法的遞歸實(shí)現(xiàn):void Preorder (BiTree T, void ( *visit)(TElemType e) / 先序遍歷二叉樹(shù) if (T) visit(T-data); / 訪(fǎng)問(wèn)結(jié)點(diǎn) Preorde

17、r(T-lchild, visit); / 遍歷左子樹(shù) Preorder(T-rchild, visit); / 遍歷右子樹(shù) 寫(xiě)法比較:int ( *visit)(TElemType &e)的含義: visit是指針,指向int類(lèi)型的函數(shù)int *visit(TElemType &e)的含義: visit是函數(shù),其返回值為指向int的指針最簡(jiǎn)單的visit函數(shù)是:Void PrintElement(TElemType e) Printf(e);例:對(duì)應(yīng)表達(dá)式 a+b*(c-d)-e/fabcde-+/f-中序遍歷此二叉樹(shù),可得到此二叉樹(shù)的中序序列為a+b*c-d-e/f (表達(dá)式的中綴表示)若

18、先序遍歷二叉樹(shù),按訪(fǎng)問(wèn)結(jié)點(diǎn)的先后次序?qū)⒔Y(jié)點(diǎn)排列起來(lái),可得到二叉樹(shù)的先序序列為 -+a*b-cd/ef (表達(dá)式的前綴表示波蘭式)后序遍歷此二叉樹(shù),可得到此二叉樹(shù)的后序序列為abcd-*+ef/- (表達(dá)式的后綴表示逆波蘭式)遍歷的遞歸執(zhí)行過(guò)程:例如:表達(dá)式a*b-c的二叉樹(shù)如下a-b*c-*abc-*abc-cb*aab*c-12先序序列:-*abc中序序列:a*b-c后序序列:ab*c-中序遍歷的非遞歸算法:BiTNode *GoFarLeft(BiTree T, Stack *S) if (!T ) return NULL; while (T-lchild ) Push(S, T); T

19、= T-lchild; return T;-*abcab*c-12TTlchildTlchildlchildTlchildlchildlchildTtoptoptoptoptopTlchildlchildrchildTlchildrchildTlchildrchildlchildTlchildrchildrchildvoid Inorder_I(BiTree T, void (*visit) (TelemType& e) Stack *S; t = GoFarLeft(T, S); / 找到最左下的結(jié)點(diǎn) while(t) visit(t-data); if (t-rchild) t = GoF

20、arLeft(t-rchild, S); else if ( !StackEmpty(S ) / 棧不空時(shí)退棧 t = Pop(S); else t = NULL; / ??毡砻鞅闅v結(jié)束 / while/ Inorder_I 遍歷算法的應(yīng)用舉例:統(tǒng)計(jì)二叉樹(shù)中葉子結(jié)點(diǎn)的個(gè)數(shù)算法基本思想: 先序(或中序或后序)遍歷二叉樹(shù),在遍歷過(guò)程中查找葉子結(jié)點(diǎn),并計(jì)數(shù)。由此,需在遍歷算法中:增添一個(gè)“計(jì)數(shù)”的參數(shù);將算法中“訪(fǎng)問(wèn)結(jié)點(diǎn)”的操作改為:若是葉子,則計(jì)數(shù)器增1。void CountLeaf (BiTree T, int& count) if ( T ) if (!T-lchild)& (!T-rchil

21、d) count+; / 對(duì)葉子結(jié)點(diǎn)計(jì)數(shù) CountLeaf( T-lchild, count); /統(tǒng)計(jì)左子樹(shù)葉子結(jié)點(diǎn) CountLeaf( T-rchild, count); /統(tǒng)計(jì)右子樹(shù)葉子結(jié)點(diǎn) / if / CountLeaf求二叉樹(shù)的深度(后序遍歷)分析:二叉樹(shù)的深度h和它的左、右子樹(shù)深度之間的關(guān)系?算法基本思想:先分別求得左、右子樹(shù)的深度;算法中“訪(fǎng)問(wèn)結(jié)點(diǎn)”的操作為:求得左、右子樹(shù)深度的最大值,然后加 1 。int Depth (BiTree T ) / 返回二叉樹(shù)的深度 if ( !T ) depthval = 0; else depthLeft = Depth( T-lchil

22、d ); /求左子樹(shù)深度 depthRight= Depth( T-rchild ); /求右子樹(shù)深度 depthval = 1 + (depthLeft depthRight ? depthLeft : depthRight); return depthval;h=maxhl, hr+1復(fù)制二叉樹(shù)(后序遍歷):其基本操作為:生成一個(gè)結(jié)點(diǎn)根元素T左子樹(shù)右子樹(shù)根元素NEWT左子樹(shù)右子樹(shù)左子樹(shù)右子樹(shù)算法思想:復(fù)制左、右子樹(shù);“訪(fǎng)問(wèn)結(jié)點(diǎn)”的操作為:生成一個(gè)結(jié)點(diǎn)。生成一個(gè)二叉樹(shù)的結(jié)點(diǎn)(其數(shù)據(jù)域?yàn)閕tem,左指針域?yàn)閘ptr,右指針域?yàn)閞ptr)BiTNode *GetTreeNode(TElemTyp

23、e item, BiTNode *lptr , BiTNode *rptr ) if (!(T = (BiTNode*)malloc(sizeof(BiTNode) exit(1); T- data = item; T- lchild = lptr; T- rchild = rptr; return T;復(fù)制:BiTNode *CopyTree(BiTNode *T) if (!T ) return NULL; if (T-lchild ) newlptr = CopyTree(T-lchild); /復(fù)制左子樹(shù) else newlptr = NULL; if (T-rchild ) newr

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

25、以下列字符串表示Status CreateBiTree(BiTree &T) /先序次序輸入結(jié)點(diǎn) scanf(&ch); if (ch= ) T = NULL; /第一個(gè)字符為空白字符 else if (!(T = (BiTNode *)malloc(sizeof(BiTNode) exit(OVERFLOW); T-data = ch; / 生成根結(jié)點(diǎn) CreateBiTree(T-lchild); / 構(gòu)造左子樹(shù) CreateBiTree(T-rchild); / 構(gòu)造右子樹(shù) return OK; / CreateBiTree上述算法的執(zhí)行過(guò)程:A B C D ABCDATBCD由二叉樹(shù)的

26、先序和中序序列建樹(shù):僅知二叉樹(shù)的先序序列“abcdefg” ,不能唯一確定一棵二叉樹(shù)。如果同時(shí)已知二叉樹(shù)的中序序列“cbdaegf”,則會(huì)如何?二叉樹(shù)的先序序列二叉樹(shù)的中序序列左子樹(shù)右子樹(shù)根左子樹(shù)右子樹(shù)根abcdefgcbdaegf例如:a b c d e f gc b d a e g faab bccddeeffggabcdefg先序序列中序序列課后作業(yè)1. P41:6.286.3.2 線(xiàn)索二叉樹(shù)何謂線(xiàn)索二叉樹(shù)?遍歷二叉樹(shù)的結(jié)果是,求得結(jié)點(diǎn)的一個(gè)線(xiàn)性序列。ABCDEFGHK例如:先序序列: A B C D E F G H K中序序列: B D C A H G K F E后序序列: D C B

27、 H K G F E A“前驅(qū)”和“后繼”的信息是在遍歷的過(guò)程中動(dòng)態(tài)得到的,不同的遍歷算法,確定的“前驅(qū)”和“后繼”是不同的!保 存?指向該線(xiàn)性序列中的“前驅(qū)”和 “后繼” 的指針,稱(chēng)作“線(xiàn)索”。A B C D E F G H K D C B E 包含“線(xiàn)索”的存儲(chǔ)結(jié)構(gòu),稱(chēng)作“線(xiàn)索鏈表”。與其相應(yīng)的二叉樹(shù),稱(chēng)作“線(xiàn)索二叉樹(shù)”。對(duì)線(xiàn)索鏈表中結(jié)點(diǎn)的約定: 在二叉鏈表的結(jié)點(diǎn)中增加兩個(gè)標(biāo)志域,并作如下規(guī)定:若該結(jié)點(diǎn)的左子樹(shù)不空, 則lchild域的指針指向其左子樹(shù),且左標(biāo)志域的值為“指針 Link”;否則,lchild域的指針指向其“前驅(qū)”,且左標(biāo)志的值為“線(xiàn)索 Thread” 。若該結(jié)點(diǎn)的右子樹(shù)不空

28、, 則rchild域的指針指向其右子樹(shù),且右標(biāo)志域的值為 “指針 Link”;否則,rchild域的指針指向其“后繼”,且右標(biāo)志的值為“線(xiàn)索 Thread”。 線(xiàn)索鏈表的存儲(chǔ)描述:typedef enum Link, Thread PointerThr; / Link=0:指針,Thread=1:線(xiàn)索typedef struct BiThrNod TElemType data; struct BiThrNode *lchild, *rchild; / 左、右指針 PointerThr LTag, RTag; / 左、右標(biāo)志 BiThrNode, *BiThrTree;lchild LTag d

29、ata RTag rchild對(duì)二叉樹(shù)以某種次序遍歷使其變?yōu)榫€(xiàn)索二叉樹(shù)的過(guò)程稱(chēng)為線(xiàn)索化。思考:一棵二叉樹(shù)的線(xiàn)索二叉樹(shù)是唯一的嗎?二叉線(xiàn)索鏈表二叉線(xiàn)索鏈表的遍歷: 添加了遍歷中得到的“前驅(qū)”和“后繼”的信息,從而簡(jiǎn)化了遍歷的算法。for ( p = firstNode(T); p; p = Succ(p) ) Visit (p);例如:對(duì)中序線(xiàn)索化鏈表的遍歷算法。中序遍歷的第一個(gè)結(jié)點(diǎn) ? 左子樹(shù)上處于“最左下”(沒(méi)有左子樹(shù))的結(jié)點(diǎn)。在中序線(xiàn)索化鏈表中結(jié)點(diǎn)的后繼 ?若結(jié)點(diǎn)無(wú)右子樹(shù), 則右鏈域所指結(jié)點(diǎn)即為其后繼;否則對(duì)其右子樹(shù)進(jìn)行中序遍歷,訪(fǎng)問(wèn)的第一個(gè)結(jié)點(diǎn)。void InOrderTraverse_

30、Thr(BiThrTree T, void (*Visit)(TElemType e) p = T-lchild; / T是頭結(jié)點(diǎn)指針,p指向根結(jié)點(diǎn) while (p != T) / 空樹(shù)或遍歷結(jié)束時(shí),p=T while (p-LTag=Link) p = p-lchild; / 找到序列中第一個(gè)結(jié)點(diǎn) if (!Visit(p-data) return ERROR;/訪(fǎng)問(wèn)左子樹(shù)為空的結(jié)點(diǎn) while (p-RTag=Thread & p-rchild!=T) p = p-rchild; Visit(p-data); / 訪(fǎng)問(wèn)后繼結(jié)點(diǎn) p = p-rchild; / p進(jìn)入其右子樹(shù)根 / InO

31、rderTraverse_Thr例如: 表達(dá)式的中序線(xiàn)索化鏈表的遍歷。abcde-+/f-NILNIL010000110000111111001111-+abcd-*ef/thrtbtpa+b*c-d-e/fppp判斷標(biāo)志域,然后沿著指針/線(xiàn)索訪(fǎng)問(wèn)后繼結(jié)點(diǎn)!如何建立線(xiàn)索鏈表?在中序遍歷過(guò)程中修改結(jié)點(diǎn)的左、右指針域,以保存當(dāng)前訪(fǎng)問(wèn)結(jié)點(diǎn)的“前驅(qū)”和“后繼”信息。遍歷過(guò)程中:附設(shè)指針pre, 并始終保持pre指向當(dāng)前訪(fǎng)問(wèn)的結(jié)點(diǎn);另設(shè)指針p指向當(dāng)前遞歸調(diào)用中正在訪(fǎng)問(wèn)的結(jié)點(diǎn),則pre指向p的前驅(qū)。void InThreading(BiThrTree p) if (p) / 對(duì)以p為根的非空二叉樹(shù)進(jìn)行線(xiàn)索化 InThreading(p-lchild); / 左子

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論