數(shù)據(jù)結(jié)構(gòu)第六章樹B課件_第1頁
數(shù)據(jù)結(jié)構(gòu)第六章樹B課件_第2頁
數(shù)據(jù)結(jié)構(gòu)第六章樹B課件_第3頁
數(shù)據(jù)結(jié)構(gòu)第六章樹B課件_第4頁
數(shù)據(jù)結(jié)構(gòu)第六章樹B課件_第5頁
已閱讀5頁,還剩29頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第6章樹和二叉樹(Tree&BinaryTree)6.1樹的基本概念6.2二叉樹6.3遍歷二叉樹和線索二叉樹6.4樹和森林6.5哈夫曼樹及其應用6.2二叉樹1. 二叉樹的定義2. 二叉樹的性質(zhì)3. 二叉樹的存儲結(jié)構(gòu)(二叉樹的運算見下一節(jié))2.二叉樹的性質(zhì)(3+2)性質(zhì)1:

在二叉樹的第i層上至多有2i-1個結(jié)點(i>0)。性質(zhì)2:

深度為k的二叉樹至多有2k-1個結(jié)點(k>0)。性質(zhì)3:

對于任何一棵二叉樹,若2度的結(jié)點數(shù)有n2個,則葉子數(shù)(n0)必定為n2+1(即n0=n2+1)對于兩種特殊形式的二叉樹(滿二叉樹和完全二叉樹),還特別具備以下2個性質(zhì):性質(zhì)4:具有n個結(jié)點的完全二叉樹的深度必為log2n+1性質(zhì)5:對完全二叉樹,若從上至下、從左至右編號,則編號為i的結(jié)點,其左孩子編號必為2i,其右孩子編號為2i+1;其雙親的編號必為i/2(i=1時為根,除外)。

3.二叉樹的存儲結(jié)構(gòu)一、順序存儲結(jié)構(gòu)按二叉樹的結(jié)點“自上而下、從左至右”編號,用一組連續(xù)的存儲單元存儲。ABCDEFGHI[1][2][3][4][5][6][7][8][9]ABCGEIDHF問:順序存儲后能否復原成唯一對應的二叉樹形狀?答:若是完全/滿二叉樹則可以做到唯一復原。而且有規(guī)律:下標值為i的雙親,其左孩子的下標值必為2i,其右孩子的下標值必為2i+1(即性質(zhì)5)例如,對應[2]的兩個孩子必為[4]和[5],即B的左孩子必是D,右孩子必為E。T[0]一般不用討論:不是完全二叉樹怎么辦?答:一律轉(zhuǎn)為完全二叉樹!方法很簡單,將各層空缺處統(tǒng)統(tǒng)補上“虛結(jié)點”,其內(nèi)容為空。AB^C^^^D^…E[1][2][3][4][5][6][7][8][9].[16]ABECD缺點:①浪費空間;②插入、刪除不便

ABCDEABCED二、鏈式存儲結(jié)構(gòu)

datal_childr_childdataLCHILDRCHILD二叉樹結(jié)點數(shù)據(jù)類型定義:typedefstructBiTNode

{

TElemType

data;

structBiTNode

*l_child,*r_child;}BiTNode,*BiTree;二叉鏈表的結(jié)點類型PARENTlchilddatarchildparent三叉鏈表的結(jié)點類型例:

ABECD^AB^D^C^^E^空指針個數(shù):2*n0+1*n1+0*n2=2n0+n1=n0+n1+n0=n0+n1+n2+1=n+1一般從根結(jié)點開始存儲。

(相應地,訪問樹中結(jié)點時也只能從根開始)^遍歷規(guī)則———二叉樹由根、左子樹、右子樹構(gòu)成,定義為D、L、R注:“先、中、后”的意思是指訪問結(jié)點D的操作是先于子樹出現(xiàn)還是后于子樹出現(xiàn)。

D、L、R的組合定義了六種可能的遍歷方案:

DLR,

LDR,LRD,

DRL,RDL,RLD

若限定先左后右,則有三種實現(xiàn)方案:

DLRLDRLRD先序遍歷中序遍歷后序遍歷

若二叉樹為空樹,則空操作;否則,(1)中序遍歷左子樹;(2)訪問根結(jié)點;(3)中序遍歷右子樹。ADBCLDRBLDRLDR>A>>D>>CLDR中序遍歷序列:BDAC中序遍歷:遍歷算法的遞歸描述Preorder(BiTreeT)

{//

先序遍歷二叉樹

if(T){

visit(T->data);//訪問結(jié)點

Preorder(T->lchild);//遍歷左子樹

Preorder(T->rchild);//遍歷右子樹

}}主程序Pre(T)返回返回pre(TR);返回返回pre(TR);ACBDTBprintf(B);pre(TL);BTAprintf(A);pre(TL);ATDprintf(D);pre(TL);DTCprintf(C);pre(TL);C返回T>左是空返回pre(TR);T>左是空返回T>右是空返回pre(TR);先序序列:ABDCT>T>對遍歷的分析:1.從前面的三種遍歷算法可以知道:如果將print語句抹去,從遞歸執(zhí)行過程看,這三種算法是完全相同的,或者說這三種算法遍歷過程中經(jīng)過結(jié)點的路線是相同的,只是訪問結(jié)點的時機不同。從虛線的出發(fā)點到終點的路線上,每個結(jié)點經(jīng)過3次。第1次經(jīng)過時訪問,是先序遍歷第2次經(jīng)過時訪問,是中序遍歷第3次經(jīng)過時訪問,是后序遍歷2.二叉樹遍歷的時間效率和空間效率時間效率:O(n)

//每個結(jié)點只訪問一次空間效率:O(n)

//棧占用的最大輔助空間AFEDCBG-+/a*b-efcd先序遍歷:中序遍歷:后序遍歷:層次遍歷:-+a*b-cd/ef-+a*b-cd/ef-+a*b-cd/ef-+a*b-cd/ef例:前綴表示中綴表示后綴表示1、統(tǒng)計二叉樹中葉子結(jié)點的個數(shù)遍歷算法的應用舉例void

CountLeaf

(BiTreeT,int&count){

if(T){

if((!T->lchild)&&(!T->rchild))count++;//對葉子結(jié)點計數(shù)

CountLeaf(T->lchild,count);

CountLeaf(

T->rchild,count);}//if}//CountLeaf思路:輸出葉子結(jié)點比較簡單,用任何一種遍歷算法,凡是左右指針均空者,則為葉子,將其統(tǒng)計并打印出來。用空格字符表示‘無孩子’或指針為空2、要實現(xiàn)遍歷運算,必須先把二叉樹存入電腦內(nèi)怎樣建樹?見教材P131例例:將下面的二叉樹以二叉鏈表形式存入計算機內(nèi)。ABGDFCE考慮1:輸入結(jié)點時怎樣表示“無孩子”?考慮2:以何種遍歷方式來輸入和建樹?將二叉樹按先序遍歷次序輸入:ABC

DE

G

F

以先序遍歷最為合適,讓每個結(jié)點都能及時被連接到位。ABGDFCE^^^^^^AB

C

D

ABCD上頁算法執(zhí)行過程舉例如下:ATBCD^^^^^

僅知二叉樹的先序序列“abcdefg”能唯一確定一棵二叉樹

如果同時已知二叉樹的中序序列“cbdaegf”,則會如何?

二叉樹的先序序列二叉樹的中序序列左子樹左子樹右子樹右子樹根根?不能特別討論:若已知先序(或后序)遍歷結(jié)果和中序遍歷結(jié)果,能否“恢復”出二叉樹?已知中序遍歷:BDCEAFHG已知后序遍歷:DECBHGFA(BDCE)(FHG)A(DCE)BFGHCDEABB已知中序遍歷和后序遍歷結(jié)果,畫出二叉樹(或給出先序遍歷結(jié)果)ACCD

C

E思考:二叉鏈表空間效率這么低,能否利用這些空閑區(qū)存放有用的信息或線索?——我們可以用它來存放當前結(jié)點在某一遍歷序列中的直接前驅(qū)和后繼等線索,以加快查找速度。用二叉鏈表法存儲包含n個結(jié)點的二叉樹,結(jié)點的指針區(qū)域中會有n+1個空指針。線索二叉樹①每個結(jié)點增加兩個域:fwd和bwd;存放前驅(qū)指針存放后繼指針如何預存這類信息?有兩種解決方法:②與原有的左右孩子指針域“復用”,充分利用那n+1個空鏈域。規(guī)定:1)若結(jié)點有左子樹,則lchild指向其左孩子;否則,lchild指向其直接前驅(qū)(即線索);2)若結(jié)點有右子樹,則rchild指向其右孩子;否則,rchild指向其直接后繼(即線索)。datalchildrchildfwdbwddatalchildrchild缺點:空間效率太低!問題:計算機如何判斷是孩子指針還是線索指針?如何區(qū)別?lchildLTagdataRTagrchild約定:當Tag域為0時,表示正常情況;當Tag域為1時,表示線索情況.前驅(qū)(后繼)左(右)孩子為區(qū)別兩種不同情況,特增加兩個標志域:問:增加了前驅(qū)和后繼等線索有什么好處?——能方便找出當前結(jié)點在某一序列中的前驅(qū)和后繼,不用堆棧(遞歸)也能遍歷整個樹。各1bit1.有關線索二叉樹的幾個術語:

線索鏈表:線索:線索二叉樹:線索化:用含Tag的結(jié)點樣式所構(gòu)成的二叉鏈表指向結(jié)點前驅(qū)和后繼的指針加上線索的二叉樹對二叉樹以某種次序遍歷使其變?yōu)榫€索二叉樹的過程線索化過程就是在遍歷過程中修改空指針的過程:將空的lchild改為結(jié)點的直接前驅(qū);將空的rchild改為結(jié)點的直接后繼。非空指針呢?仍然指向孩子結(jié)點(稱為“正常情況”)ABCGEIDHFroot懸空?NIL懸空?NIL解:對該二叉樹中序遍歷的結(jié)果為:

H,D,I,B,E,A,F,C,G所以添加線索應當按如下路徑進行:為避免懸空態(tài),應增設一個頭結(jié)點例1:畫出以下二叉樹對應的中序線索二叉樹。2.線索二叉樹的生成——線索化線索化過程就是在遍歷過程中修改空指針的過程00A00C00B11E11F11G00D11I11H注:此圖中序遍歷結(jié)果為:H,D,I,B,E,A,F,C,

G對應的中序線索二叉樹存儲結(jié)構(gòu)(鏈表)如圖所示:0root0例2:給定如圖所示二叉樹T,請畫出與其對應的中序線索二叉樹。

2825405560330854解:因為中序遍歷序列是:5540256028083354對應線索樹應當按此規(guī)律連線,即在原二叉樹中添加虛線。NILNIL3.線索二叉樹的遍歷(無需堆棧)對于線索二叉樹的遍歷,只要找到序列中的第一個結(jié)點,然后依次訪問結(jié)點的后繼直到后繼為

溫馨提示

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

評論

0/150

提交評論