九九热最新网址,777奇米四色米奇影院在线播放,国产精品18久久久久久久久久,中文有码视频,亚洲一区在线免费观看,国产91精品在线,婷婷丁香六月天

歡迎來(lái)到裝配圖網(wǎng)! | 幫助中心 裝配圖網(wǎng)zhuangpeitu.com!
裝配圖網(wǎng)
ImageVerifierCode 換一換
首頁(yè) 裝配圖網(wǎng) > 資源分類 > PPT文檔下載  

數(shù)據(jù)結(jié)構(gòu)嚴(yán)蔚敏第6章

  • 資源ID:48642145       資源大?。?span id="24d9guoke414" class="font-tahoma">1.87MB        全文頁(yè)數(shù):141頁(yè)
  • 資源格式: PPT        下載積分:10積分
快捷下載 游客一鍵下載
會(huì)員登錄下載
微信登錄下載
三方登錄下載: 微信開(kāi)放平臺(tái)登錄 支付寶登錄   QQ登錄   微博登錄  
二維碼
微信掃一掃登錄
下載資源需要10積分
郵箱/手機(jī):
溫馨提示:
用戶名和密碼都是您填寫的郵箱或者手機(jī)號(hào),方便查詢和重復(fù)下載(系統(tǒng)自動(dòng)生成)
支付方式: 支付寶    微信支付   
驗(yàn)證碼:   換一換

 
賬號(hào):
密碼:
驗(yàn)證碼:   換一換
  忘記密碼?
    
友情提示
2、PDF文件下載后,可能會(huì)被瀏覽器默認(rèn)打開(kāi),此種情況可以點(diǎn)擊瀏覽器菜單,保存網(wǎng)頁(yè)到桌面,就可以正常下載了。
3、本站不支持迅雷下載,請(qǐng)使用電腦自帶的IE瀏覽器,或者360瀏覽器、谷歌瀏覽器下載即可。
4、本站資源下載后的文檔和圖紙-無(wú)水印,預(yù)覽文檔經(jīng)過(guò)壓縮,下載后原文更清晰。
5、試題試卷類文檔,如果標(biāo)題沒(méi)有明確說(shuō)明有答案則都視為沒(méi)有答案,請(qǐng)知曉。

數(shù)據(jù)結(jié)構(gòu)嚴(yán)蔚敏第6章

第六章第六章樹(shù)和二叉樹(shù)樹(shù)和二叉樹(shù)教學(xué)目的和要求教學(xué)目的和要求 1、熟練掌握二叉樹(shù)的結(jié)構(gòu)特點(diǎn),了解相應(yīng)的證明。、熟練掌握二叉樹(shù)的結(jié)構(gòu)特點(diǎn),了解相應(yīng)的證明。 2、熟悉二叉樹(shù)的各種存儲(chǔ)結(jié)構(gòu)的特點(diǎn)及適用范圍。、熟悉二叉樹(shù)的各種存儲(chǔ)結(jié)構(gòu)的特點(diǎn)及適用范圍。 3、掌握二叉樹(shù)遍歷的遞歸與非遞歸算法。、掌握二叉樹(shù)遍歷的遞歸與非遞歸算法。 4、掌握二叉線索樹(shù)的相關(guān)算法。、掌握二叉線索樹(shù)的相關(guān)算法。 5、熟悉樹(shù)的各種存儲(chǔ)結(jié)構(gòu)及特點(diǎn),掌握樹(shù)和森林、熟悉樹(shù)的各種存儲(chǔ)結(jié)構(gòu)及特點(diǎn),掌握樹(shù)和森林與二叉樹(shù)的方法。與二叉樹(shù)的方法。 6、了解最優(yōu)樹(shù)的特性,掌握最優(yōu)樹(shù)和哈夫曼編碼、了解最優(yōu)樹(shù)的特性,掌握最優(yōu)樹(shù)和哈夫曼編碼的方法。的方法。 1數(shù)據(jù)的邏輯結(jié)構(gòu) 2、數(shù)據(jù)的存儲(chǔ)結(jié)構(gòu) 3、數(shù)據(jù)的運(yùn)算:檢索、排序、插入、刪除、修改等。 A線性結(jié)構(gòu) B非線性結(jié)構(gòu)A 順序存儲(chǔ) B 鏈?zhǔn)酱鎯?chǔ) 線性表?xiàng)j?duì)樹(shù)形結(jié)構(gòu)圖形結(jié)構(gòu)數(shù)據(jù)結(jié)構(gòu)的三個(gè)主要問(wèn)題 樹(shù)形結(jié)構(gòu)樹(shù)形結(jié)構(gòu)全校學(xué)生檔案管理的組織方式全校學(xué)生檔案管理的組織方式ABCDEFGH樹(shù)形結(jié)構(gòu)樹(shù)形結(jié)構(gòu) 結(jié)點(diǎn)間具有分層次的連接關(guān)系結(jié)點(diǎn)間具有分層次的連接關(guān)系HBCDEFGA6.1 樹(shù)的類型定義樹(shù)的類型定義6.2 6.2 二叉樹(shù)的類型定義二叉樹(shù)的類型定義6.3 二叉樹(shù)的存儲(chǔ)結(jié)構(gòu)二叉樹(shù)的存儲(chǔ)結(jié)構(gòu)6.4 二叉樹(shù)的遍歷二叉樹(shù)的遍歷6.5 線索二叉樹(shù)線索二叉樹(shù)6.6 樹(shù)和森林的表示方法樹(shù)和森林的表示方法6.7 樹(shù)和森林的遍歷樹(shù)和森林的遍歷6.8 哈夫曼樹(shù)與哈夫曼編碼哈夫曼樹(shù)與哈夫曼編碼6.1 樹(shù)的類型定義樹(shù)的類型定義數(shù)據(jù)對(duì)象數(shù)據(jù)對(duì)象 D:D是具有相同特性的數(shù)據(jù)元素的集合。是具有相同特性的數(shù)據(jù)元素的集合。 若若D為空集,則稱為空樹(shù)為空集,則稱為空樹(shù) 。 否則否則: (1) 在在D中存在唯一的稱為根的數(shù)據(jù)元素中存在唯一的稱為根的數(shù)據(jù)元素root; (2) 當(dāng)當(dāng)n1時(shí),其余結(jié)點(diǎn)可分為時(shí),其余結(jié)點(diǎn)可分為m (m0)個(gè)互個(gè)互 不相交的有限集不相交的有限集T1, T2, , Tm,其中每一,其中每一 棵子集本身又是一棵符合本定義的樹(shù),棵子集本身又是一棵符合本定義的樹(shù), 稱為根稱為根root的子樹(shù)。的子樹(shù)。 數(shù)據(jù)關(guān)系數(shù)據(jù)關(guān)系 R:ABCDEFGHIJMKLA( B(E, F(K, L), C(G), D(H, I, J(M) )T1T3T2樹(shù)根例如例如: : 基本操作:基本操作:查查 找找 類類 插插 入入 類類刪刪 除除 類類 Root(T) / 求樹(shù)的根結(jié)點(diǎn)求樹(shù)的根結(jié)點(diǎn) 查找類:查找類:Value(T, cur_e) / 求當(dāng)前結(jié)點(diǎn)的元素值求當(dāng)前結(jié)點(diǎn)的元素值 Parent(T, cur_e) / 求當(dāng)前結(jié)點(diǎn)的雙親結(jié)點(diǎn)求當(dāng)前結(jié)點(diǎn)的雙親結(jié)點(diǎn)LeftChild(T, cur_e) / 求當(dāng)前結(jié)點(diǎn)的最左孩子求當(dāng)前結(jié)點(diǎn)的最左孩子 RightSibling(T, cur_e) / 求當(dāng)前結(jié)點(diǎn)的右兄弟求當(dāng)前結(jié)點(diǎn)的右兄弟TreeEmpty(T) / 判定樹(shù)是否為空樹(shù)判定樹(shù)是否為空樹(shù) TreeDepth(T) / 求樹(shù)的深度求樹(shù)的深度TraverseTree( T, Visit() ) / 遍歷遍歷InitTree(&T) / 初始化置空樹(shù)初始化置空樹(shù) 插入類:插入類:CreateTree(&T, definition) / 按定義構(gòu)造樹(shù)按定義構(gòu)造樹(shù)Assign(T, cur_e, value) / 給當(dāng)前結(jié)點(diǎn)賦值給當(dāng)前結(jié)點(diǎn)賦值InsertChild(&T, &p, i, c) / 將以將以c為根的樹(shù)插入為結(jié)點(diǎn)為根的樹(shù)插入為結(jié)點(diǎn)p的第的第i棵子樹(shù)棵子樹(shù) ClearTree(&T) / 將樹(shù)清空將樹(shù)清空 刪除類:刪除類:DestroyTree(&T) / 銷毀樹(shù)的結(jié)構(gòu)銷毀樹(shù)的結(jié)構(gòu)DeleteChild(&T, &p, i) / 刪除結(jié)點(diǎn)刪除結(jié)點(diǎn)p的第的第i棵子樹(shù)棵子樹(shù)對(duì)比對(duì)比樹(shù)型結(jié)構(gòu)樹(shù)型結(jié)構(gòu)和和線性結(jié)構(gòu)線性結(jié)構(gòu)的結(jié)構(gòu)特點(diǎn)的結(jié)構(gòu)特點(diǎn)線性結(jié)構(gòu)線性結(jié)構(gòu)樹(shù)型結(jié)構(gòu)樹(shù)型結(jié)構(gòu)第一個(gè)數(shù)據(jù)元素第一個(gè)數(shù)據(jù)元素 ( (無(wú)前驅(qū)無(wú)前驅(qū)) ) 根結(jié)點(diǎn)根結(jié)點(diǎn) ( (無(wú)前驅(qū)無(wú)前驅(qū)) )最后一個(gè)數(shù)據(jù)元素最后一個(gè)數(shù)據(jù)元素 (無(wú)后繼無(wú)后繼)多個(gè)葉子結(jié)點(diǎn)多個(gè)葉子結(jié)點(diǎn) ( (無(wú)后繼無(wú)后繼) )其它數(shù)據(jù)元素其它數(shù)據(jù)元素( (一個(gè)前驅(qū)、一個(gè)前驅(qū)、 一個(gè)后繼一個(gè)后繼) )其它數(shù)據(jù)元素其它數(shù)據(jù)元素( (一個(gè)前驅(qū)、一個(gè)前驅(qū)、 多個(gè)后繼多個(gè)后繼) )基基 本本 術(shù)術(shù) 語(yǔ)語(yǔ)結(jié)點(diǎn)結(jié)點(diǎn): :結(jié)點(diǎn)的度結(jié)點(diǎn)的度: :樹(shù)的度樹(shù)的度: :葉子結(jié)點(diǎn)葉子結(jié)點(diǎn): :分支結(jié)點(diǎn)分支結(jié)點(diǎn): :數(shù)據(jù)元素+ +若干指向子樹(shù)的分支分支的個(gè)數(shù)樹(shù)中所有結(jié)點(diǎn)的度的最大值度為零的結(jié)點(diǎn)度大于零的結(jié)點(diǎn)DHIJM(從根到結(jié)點(diǎn)的)路徑路徑:孩子孩子結(jié)點(diǎn)、雙親雙親結(jié)點(diǎn)兄弟兄弟結(jié)點(diǎn)、堂兄弟祖先祖先結(jié)點(diǎn)、子孫子孫結(jié)點(diǎn)結(jié)點(diǎn)的層次結(jié)點(diǎn)的層次: :樹(shù)的深度:樹(shù)的深度: 由從根根到該結(jié)點(diǎn)所經(jīng)分支和結(jié)點(diǎn)構(gòu)成ABCDEFGHIJMKL假設(shè)根結(jié)點(diǎn)的層次為1,第l 層的結(jié)點(diǎn)的子樹(shù)根結(jié)點(diǎn)的層次為l+1樹(shù)中葉子結(jié)點(diǎn)所在的最大層次任何一棵非空樹(shù)是一個(gè)二元組 Tree = (root,F(xiàn))其中:root 被稱為根結(jié)點(diǎn) F 被稱為子樹(shù)森林森林:森林:是m(m0)棵互不相交的樹(shù)的集合ArootBCDEFGHIJMKLF6.2 二叉樹(shù)的類型定義二叉樹(shù)的類型定義 二叉樹(shù)或?yàn)榭諛?shù)空樹(shù),或是由一個(gè)根結(jié)根結(jié)點(diǎn)點(diǎn)加上兩棵兩棵分別稱為左子樹(shù)左子樹(shù)和右子樹(shù)的、互不交的互不交的二叉樹(shù)二叉樹(shù)組成。ABCDEFGHK根結(jié)點(diǎn)左子樹(shù)右子樹(shù)二叉樹(shù)的五種基本形態(tài):二叉樹(shù)的五種基本形態(tài):N空樹(shù)空樹(shù)只含根結(jié)點(diǎn)只含根結(jié)點(diǎn)NNNLRR右子樹(shù)為空樹(shù)右子樹(shù)為空樹(shù)L左子樹(shù)為空樹(shù)左子樹(shù)為空樹(shù)左右子左右子樹(shù)均不樹(shù)均不為空樹(shù)為空樹(shù) 二叉樹(shù)的主要基本操作二叉樹(shù)的主要基本操作:查查 找找 類類插插 入入 類類刪刪 除除 類類 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, Visit(); PostOrderTraverse(T, Visit(); LevelOrderTraverse(T, Visit(); InitBiTree(&T); Assign(T, &e, value); CreateBiTree(&T, definition); InsertChild(T, p, LR, c);ClearBiTree(&T); DestroyBiTree(&T);DeleteChild(T, p, LR);二叉樹(shù)二叉樹(shù)的重要特性的重要特性 性質(zhì)性質(zhì) 1 : 在二叉樹(shù)的第 i 層上至多有2i-1 個(gè)結(jié)點(diǎn)。 (i1)用歸納法證明用歸納法證明: 歸納基歸納基: 歸納假設(shè):歸納假設(shè): 歸納證明:歸納證明:i = 1 層時(shí),只有一個(gè)根結(jié)點(diǎn): 2i-1 = 20 = 1;假設(shè)對(duì)所有的 j,1 j i,命題成立;二叉樹(shù)上每個(gè)結(jié)點(diǎn)至多有兩棵子樹(shù),則第 i 層的結(jié)點(diǎn)數(shù) = 2i-2 2 = 2i-1 。性質(zhì)性質(zhì) 2 : 深度為 k 的二叉樹(shù)上至多含 2k-1 個(gè)結(jié)點(diǎn)(k1)。證明:證明: 基于上一條性質(zhì),深度為 k 的二叉樹(shù)上的結(jié)點(diǎn)數(shù)至多為 20+21+ +2k-1 = 2k-1 。 性質(zhì)性質(zhì) 3 : 對(duì)任何一棵二叉樹(shù),若它含有n0 個(gè)葉子結(jié)點(diǎn)、n2 個(gè)度為 2 的結(jié)點(diǎn),則必存在關(guān)系式:n0 = n2+1。證明:證明:設(shè)設(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 。兩類兩類特殊特殊的二叉樹(shù):的二叉樹(shù):滿二叉樹(shù)滿二叉樹(shù):指的是深度為k且含有2k-1個(gè)結(jié)點(diǎn)的二叉樹(shù)。完全二叉樹(shù)完全二叉樹(shù):樹(shù)中所含的 n 個(gè)結(jié)點(diǎn)和滿二叉樹(shù)中編號(hào)編號(hào)為為 1 至至 n 的結(jié)點(diǎn)的結(jié)點(diǎn)一一對(duì)應(yīng)。123456789 10 11 12 13 14 15abcdefghij 性質(zhì)性質(zhì) 4 : 具有 n 個(gè)結(jié)點(diǎn)的完全二叉樹(shù)的深度深度為 log2n +1 。證明:證明:設(shè)設(shè)完全二叉樹(shù)的深度為 k 則根據(jù)第二條性質(zhì)得 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)。6.3 二叉樹(shù)的存儲(chǔ)結(jié)構(gòu)二叉樹(shù)的存儲(chǔ)結(jié)構(gòu)二、二叉樹(shù)的鏈?zhǔn)蕉?、二叉?shù)的鏈?zhǔn)?存儲(chǔ)表示存儲(chǔ)表示一、一、 二叉樹(shù)的順序二叉樹(shù)的順序 存儲(chǔ)表示存儲(chǔ)表示#define MAX_TREE_SIZE 100 / 二叉樹(shù)的最大結(jié)點(diǎn)數(shù)typedef TElemType SqBiTreeMAX_ TREE_SIZE; / 0號(hào)單元存儲(chǔ)根結(jié)點(diǎn)SqBiTree bt;一、一、 二叉樹(shù)的順序存儲(chǔ)表示二叉樹(shù)的順序存儲(chǔ)表示例如例如:ABCDEF A B D C E F 0 1 2 3 4 5 6 7 8 9 10 11 12 131401326順序存儲(chǔ)結(jié)構(gòu)僅適用于完全二叉樹(shù)!順序存儲(chǔ)結(jié)構(gòu)僅適用于完全二叉樹(shù)!二、二叉樹(shù)的鏈?zhǔn)酱鎯?chǔ)表示二、二叉樹(shù)的鏈?zhǔn)酱鎯?chǔ)表示1. 1. 二叉鏈表二叉鏈表2三叉鏈表三叉鏈表3 3雙親鏈表雙親鏈表4線索鏈表線索鏈表ADEBCF rootlchild data rchild結(jié)點(diǎn)結(jié)構(gòu)結(jié)點(diǎn)結(jié)構(gòu):1. 1. 二叉鏈表二叉鏈表typedef struct BiTNode / 結(jié)點(diǎn)結(jié)構(gòu)結(jié)點(diǎn)結(jié)構(gòu) TElemType data; struct BiTNode *lchild, *rchild; / 左右孩子指針 BiTNode, *BiTree;lchild data rchild結(jié)點(diǎn)結(jié)構(gòu)結(jié)點(diǎn)結(jié)構(gòu):C 語(yǔ)言的類型描述如下語(yǔ)言的類型描述如下: :ADEBCF root 2三叉鏈表三叉鏈表parent lchild data rchild結(jié)點(diǎn)結(jié)構(gòu)結(jié)點(diǎn)結(jié)構(gòu): typedef struct TriTNode / 結(jié)點(diǎn)結(jié)構(gòu)結(jié)點(diǎn)結(jié)構(gòu) TElemType data; struct TriTNode *lchild, *rchild; / 左右孩子指針 struct TriTNode *parent; /雙親指針 TriTNode, *TriTree;parent lchild data rchild結(jié)點(diǎn)結(jié)構(gòu)結(jié)點(diǎn)結(jié)構(gòu):C 語(yǔ)言的類型描述如下語(yǔ)言的類型描述如下: :0123456B2C0A -1D2E3F4 data parent結(jié)點(diǎn)結(jié)構(gòu)結(jié)點(diǎn)結(jié)構(gòu):3 3雙親鏈表雙親鏈表LRTagLRRRL typedef struct BPTNode / 結(jié)點(diǎn)結(jié)構(gòu)結(jié)點(diǎn)結(jié)構(gòu) TElemType data; int *parent; / 指向雙親的指針 char LRTag; / 左、右孩子標(biāo)志域 BPTNode typedef struct BPTree / 樹(shù)結(jié)構(gòu)樹(shù)結(jié)構(gòu) BPTNode nodesMAX_TREE_SIZE; int num_node; / 結(jié)點(diǎn)數(shù)目 int root; / 根結(jié)點(diǎn)的位置 BPTree6.4二叉樹(shù)的遍歷二叉樹(shù)的遍歷一、問(wèn)題的提出一、問(wèn)題的提出二、先左后右的遍歷算法二、先左后右的遍歷算法三、算法的遞歸描述三、算法的遞歸描述四、中序遍歷算法的非遞歸描述四、中序遍歷算法的非遞歸描述五五、遍歷算法的應(yīng)用舉例遍歷算法的應(yīng)用舉例 順著某一條搜索路徑巡訪巡訪二叉樹(shù)中的結(jié)點(diǎn),使得每個(gè)結(jié)點(diǎn)均被訪問(wèn)一均被訪問(wèn)一次次,而且僅被訪問(wèn)一次僅被訪問(wèn)一次。一、問(wèn)題的提出一、問(wèn)題的提出“訪問(wèn)訪問(wèn)”的含義可以很廣,如:輸出結(jié)點(diǎn)的信息等。 “遍歷遍歷”是任何類型均有的操作,對(duì)線性結(jié)構(gòu)而言,只有一條搜索路徑(因?yàn)槊總€(gè)結(jié)點(diǎn)均只有一個(gè)后繼),故不需要另加討論。而二叉樹(shù)是非線性結(jié)構(gòu), 每個(gè)結(jié)點(diǎn)有兩個(gè)后繼每個(gè)結(jié)點(diǎn)有兩個(gè)后繼,則存在如何遍歷存在如何遍歷即按什么樣的搜索搜索路徑路徑遍歷的問(wèn)題。 對(duì)對(duì)“二叉樹(shù)二叉樹(shù)”而言,可以有而言,可以有三條搜索路徑:三條搜索路徑: 1先上后下先上后下的按層次遍歷; 2先左先左(子樹(shù))后右后右(子樹(shù))的遍歷; 3先右先右(子樹(shù))后左后左(子樹(shù))的遍歷。二、先左后右的遍歷算法二、先左后右的遍歷算法先先序(根)的遍歷算法中中序(根)的遍歷算法后后序(根)的遍歷算法 若二叉樹(shù)為空樹(shù),則空操作;否則,(1)訪問(wèn)根結(jié)點(diǎn);(2)先序遍歷左子樹(shù);(3)先序遍歷右子樹(shù)。先序(根)的遍歷算法:先序(根)的遍歷算法: 若二叉樹(shù)為空樹(shù),則空操作;否則,(1)中序遍歷左子樹(shù);(2)訪問(wèn)根結(jié)點(diǎn);(3)中序遍歷右子樹(shù)。中序(根)的遍歷算法:中序(根)的遍歷算法: 若二叉樹(shù)為空樹(shù),則空操作;否則,(1)后序遍歷左子樹(shù);(2)后序遍歷右子樹(shù);(3)訪問(wèn)根結(jié)點(diǎn)。后序(根)的遍歷算法:后序(根)的遍歷算法:課堂提問(wèn): 有以下結(jié)構(gòu)的二叉樹(shù)有以下結(jié)構(gòu)的二叉樹(shù) 寫出其先序、中序和后序遍歷的序列寫出其先序、中序和后序遍歷的序列ABCDE三、算法的遞歸描述三、算法的遞歸描述void Preorder (BiTree T, void( *visit)(TElemType& e) / 先序遍歷二叉樹(shù) if (T) visit(T-data); / 訪問(wèn)結(jié)點(diǎn) Preorder(T-lchild, visit); / 遍歷左子樹(shù) Preorder(T-rchild, visit);/ 遍歷右子樹(shù) 四、中序遍歷算法的非遞歸描述四、中序遍歷算法的非遞歸描述BiTNode *GoFarLeft(BiTree T, Stack *S) if (!T ) return NULL; while (T-lchild ) Push(S, T); T = T-lchild; return T; void 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 = GoFarLeft(t-rchild, S); else if ( !StackEmpty(S ) / 棧不空時(shí)退棧 t = Pop(S); else t = NULL; / ??毡砻鞅闅v結(jié)束 / while/ Inorder_I 五五、遍歷算法的應(yīng)用舉例遍歷算法的應(yīng)用舉例1、統(tǒng)計(jì)二叉樹(shù)中葉子結(jié)點(diǎn)的個(gè)數(shù)、統(tǒng)計(jì)二叉樹(shù)中葉子結(jié)點(diǎn)的個(gè)數(shù) (先序遍歷先序遍歷)2、求二叉樹(shù)的深度、求二叉樹(shù)的深度(后序遍歷后序遍歷)3、復(fù)制二叉樹(shù)、復(fù)制二叉樹(shù)(后序遍歷后序遍歷)4 4、建立二叉樹(shù)的存儲(chǔ)結(jié)構(gòu)、建立二叉樹(shù)的存儲(chǔ)結(jié)構(gòu)1、統(tǒng)計(jì)二叉樹(shù)中葉子結(jié)點(diǎn)的個(gè)數(shù)、統(tǒng)計(jì)二叉樹(shù)中葉子結(jié)點(diǎn)的個(gè)數(shù)算法基本思想算法基本思想: : 先序(或中序或后序)遍歷二叉樹(shù),在遍歷過(guò)程中查找葉子結(jié)點(diǎn),并計(jì)數(shù)。由此,需在遍歷算法中增添一個(gè)需在遍歷算法中增添一個(gè)“計(jì)數(shù)計(jì)數(shù)”的參數(shù),的參數(shù),并將算法中“訪問(wèn)結(jié)點(diǎn)”的操作改為:若是葉子,則計(jì)數(shù)器增若是葉子,則計(jì)數(shù)器增1 1。void CountLeaf (BiTree T, int& count) if ( T ) if (!T-lchild)& (!T-rchild) count+; / 對(duì)葉子結(jié)點(diǎn)計(jì)數(shù) CountLeaf( T-lchild, count); CountLeaf( T-rchild, count); / if / CountLeaf2、求二叉樹(shù)的深度、求二叉樹(shù)的深度(后序遍歷后序遍歷)算法基本思想算法基本思想: : 從二叉樹(shù)深度的定義可知,二叉樹(shù)的二叉樹(shù)的深度應(yīng)為其左、右子樹(shù)深度的最大值加深度應(yīng)為其左、右子樹(shù)深度的最大值加1 1。由此,需先分別求得左、右子樹(shù)的深度,需先分別求得左、右子樹(shù)的深度,算法中“訪問(wèn)結(jié)點(diǎn)”的操作為:求得左、求得左、右子樹(shù)深度的最大值,然后加右子樹(shù)深度的最大值,然后加 1 1 。 首先分析二叉樹(shù)的深度二叉樹(shù)的深度和它的左左、右子右子樹(shù)深度樹(shù)深度之間的關(guān)系。int Depth (BiTree T ) / 返回二叉樹(shù)的深度 if ( !T ) depthval = 0; else depthLeft = Depth( T-lchild ); depthRight= Depth( T-rchild ); depthval = 1 + (depthLeft depthRight ? depthLeft : depthRight); return depthval;3、復(fù)制二叉樹(shù)、復(fù)制二叉樹(shù)其基本操作為:生成一個(gè)結(jié)點(diǎn)。其基本操作為:生成一個(gè)結(jié)點(diǎn)。根元素根元素T左子樹(shù)左子樹(shù)右子樹(shù)右子樹(shù)根元素根元素NEWT左子樹(shù)左子樹(shù)右子樹(shù)右子樹(shù)左子樹(shù)左子樹(shù)右子樹(shù)右子樹(shù)(后序遍歷后序遍歷)BiTNode *GetTreeNode(TElemType item, BiTNode *lptr , BiTNode *rptr ) if (!(T = (BiTNode*)malloc(sizeof(BiTNode) exit(OVERFLOW); T- data = item; T- lchild = lptr; T- rchild = rptr; return T; 生成一個(gè)二叉樹(shù)的結(jié)點(diǎn)生成一個(gè)二叉樹(shù)的結(jié)點(diǎn)(其數(shù)據(jù)域?yàn)槠鋽?shù)據(jù)域?yàn)閕tem,左指針域?yàn)樽笾羔樣驗(yàn)閘ptr,右指針域?yàn)橛抑羔樣驗(yàn)閞ptr)BiTNode *CopyTree(BiTNode *T) if (!T ) return NULL; if (T-lchild ) newlptr = CopyTree(T-lchild);/復(fù)制左子樹(shù) else newlptr = NULL; if (T-rchild ) newrptr = CopyTree(T-rchild);/復(fù)制右子樹(shù) else newrptr = NULL; newT = GetTreeNode(T-data, newlptr, newrptr); return newT; / CopyTreeABCDEFGHK D C B H K G F E A例如:下列二叉樹(shù)例如:下列二叉樹(shù)的復(fù)制過(guò)程如下:的復(fù)制過(guò)程如下:newT4 4、建立二叉樹(shù)的存儲(chǔ)、建立二叉樹(shù)的存儲(chǔ)結(jié)構(gòu)結(jié)構(gòu)不同的定義方法相應(yīng)有不同的不同的定義方法相應(yīng)有不同的存儲(chǔ)結(jié)構(gòu)的建立算法存儲(chǔ)結(jié)構(gòu)的建立算法以字符串“A!”表示 以字符串的形式以字符串的形式 根根 左子樹(shù)左子樹(shù) 右子樹(shù)右子樹(shù)定義一棵二叉樹(shù)定義一棵二叉樹(shù)例如:ABCD以字符“!”表示A(B(! ,C(! , ! ),D(! , ! )空樹(shù)空樹(shù)只含一個(gè)根結(jié)點(diǎn)只含一個(gè)根結(jié)點(diǎn)的二叉樹(shù)的二叉樹(shù)A以下列字符串表示Status CreateBiTree(BiTree &T) scanf(&ch); if (ch=!) T = NULL; 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 僅知二叉樹(shù)的先序序列“abcdefg” 不能唯一確定一棵二叉樹(shù),由二叉樹(shù)的先序和中序序列建樹(shù)由二叉樹(shù)的先序和中序序列建樹(shù) 如果同時(shí)已知二叉樹(shù)的中序序列“cbdaegf”,則會(huì)如何? 二叉樹(shù)的先序序列二叉樹(shù)的中序序列左子樹(shù)左子樹(shù)左子樹(shù)左子樹(shù) 右子樹(shù)右子樹(shù)右子樹(shù)右子樹(shù)根根根根a b c d e f gc b d a e g f例如例如: :aab bccddeeffggabcdefg先序序列中序序列void CrtBT(BiTree& T, char pre, char ino, int ps, int is, int n ) / 已知preps.ps+n-1為二叉樹(shù)的先序序列, / insis.is+n-1為二叉樹(shù)的中序序列,本算 / 法由此兩個(gè)序列構(gòu)造二叉鏈表 if (n=0) T=NULL; else k=Search(ino, preps); / 在中序序列中查詢 if (k= -1) T=NULL; else / / CrtBT T=(BiTNode*)malloc(sizeof(BiTNode);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+(k-is)+1, k+1, n-(k-is)-1 );練習(xí)題:練習(xí)題: 1、編寫遞歸算法,將二叉樹(shù)中所有結(jié)點(diǎn)、編寫遞歸算法,將二叉樹(shù)中所有結(jié)點(diǎn)的左、右子樹(shù)交換。的左、右子樹(shù)交換。 2、編寫遞歸算法:對(duì)于二叉樹(shù)中每一個(gè)、編寫遞歸算法:對(duì)于二叉樹(shù)中每一個(gè)元素值為元素值為x的結(jié)點(diǎn),刪除以它為根的子樹(shù),的結(jié)點(diǎn),刪除以它為根的子樹(shù),并釋放相應(yīng)的空間。并釋放相應(yīng)的空間。 3、編寫按層次順序(同一層自左至右)、編寫按層次順序(同一層自左至右)遍歷二叉樹(shù)的算法。遍歷二叉樹(shù)的算法。6.5線索二叉樹(shù)線索二叉樹(shù) 何謂線索二叉樹(shù)?何謂線索二叉樹(shù)? 線索鏈表的遍歷算法線索鏈表的遍歷算法 如何建立線索鏈表?如何建立線索鏈表?一、一、何謂線索二叉樹(shù)?何謂線索二叉樹(shù)?遍歷二叉樹(shù)的結(jié)果是, 求得結(jié)點(diǎn)的一個(gè)線性序列。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ū)”和 “后繼” 的指針指針,稱作“線線索索”與其相應(yīng)的二叉樹(shù),稱作 “線索二叉樹(shù)線索二叉樹(shù)”包含 “線索” 的存儲(chǔ)結(jié)構(gòu),稱作 “線索鏈線索鏈表表”A B C D E F G H K D C B E 對(duì)對(duì)線索鏈表線索鏈表中結(jié)點(diǎn)的約定:中結(jié)點(diǎn)的約定: 在二叉鏈表的結(jié)點(diǎn)中增加兩個(gè)標(biāo)志域增加兩個(gè)標(biāo)志域,并作如下規(guī)定:若該結(jié)點(diǎn)的左子樹(shù)不空,若該結(jié)點(diǎn)的左子樹(shù)不空,則Lchild域的指針指向其左子樹(shù), 且左標(biāo)志域的值為“指針 Link”; 否則,Lchild域的指針指向其“前驅(qū)”, 且左標(biāo)志的值為“線索 Thread” 。若該結(jié)點(diǎn)的右子樹(shù)不空,若該結(jié)點(diǎn)的右子樹(shù)不空,則rchild域的指針指向其右子樹(shù), 且右標(biāo)志域的值為 “指針 Link”;否則,rchild域的指針指向其“后繼”, 且右標(biāo)志的值為“線索 Thread”。 如此定義的二叉樹(shù)的存儲(chǔ)結(jié)構(gòu)稱作如此定義的二叉樹(shù)的存儲(chǔ)結(jié)構(gòu)稱作“線索鏈表線索鏈表”。typedef struct BiThrNod TElemType data; struct BiThrNode *lchild, *rchild; / 左右指針 PointerThr LTag, RTag; / 左右標(biāo)志 BiThrNode, *BiThrTree;線索鏈表的類型描述: typedef enum Link, Thread PointerThr; / Link=0:指針,Thread=1:線索二、線索鏈表的遍歷算法二、線索鏈表的遍歷算法: for ( p = firstNode(T); p; p = Succ(p) ) Visit (p);由于在線索鏈表中添加了遍歷中得到的“前驅(qū)”和“后繼”的信息,從而簡(jiǎn)化了遍歷的算法。例如例如: 對(duì)中序線索化鏈表的遍歷算法對(duì)中序線索化鏈表的遍歷算法 中序遍歷的第一個(gè)結(jié)點(diǎn)中序遍歷的第一個(gè)結(jié)點(diǎn) ? 在中序線索化鏈表中結(jié)點(diǎn)的后繼在中序線索化鏈表中結(jié)點(diǎn)的后繼 ?左子樹(shù)上處于“最左下最左下”(沒(méi)有左子樹(shù))的結(jié)點(diǎn)。若若無(wú)右子樹(shù),則為則為后繼線索后繼線索所指結(jié)點(diǎn);否則為否則為對(duì)其右子樹(shù)右子樹(shù)進(jìn)行中序遍歷遍歷時(shí)訪問(wèn)的第一個(gè)結(jié)點(diǎn)。第一個(gè)結(jié)點(diǎn)。void InOrderTraverse_Thr(BiThrTree T, void (*Visit)(TElemType e) p = T-lchild; / 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; while (p-RTag=Thread & p-rchild!=T) p = p-rchild; Visit(p-data); / 訪問(wèn)后繼結(jié)點(diǎn) p = p-rchild; / p進(jìn)至其右子樹(shù)根 / InOrderTraverse_Thr 在中序遍歷過(guò)程中修改結(jié)點(diǎn)的在中序遍歷過(guò)程中修改結(jié)點(diǎn)的左、右指針域,以保存當(dāng)前訪問(wèn)結(jié)左、右指針域,以保存當(dāng)前訪問(wèn)結(jié)點(diǎn)的點(diǎn)的“前驅(qū)前驅(qū)”和和“后繼后繼”信息。遍歷過(guò)信息。遍歷過(guò)程中,附設(shè)指針程中,附設(shè)指針pre, 并始終保持指并始終保持指針針pre指向當(dāng)前訪問(wèn)的、指針指向當(dāng)前訪問(wèn)的、指針p所指所指結(jié)點(diǎn)的前驅(qū)。結(jié)點(diǎn)的前驅(qū)。三、如何建立線索鏈表?三、如何建立線索鏈表?void InThreading(BiThrTree p) if (p) / 對(duì)以p為根的非空二叉樹(shù)進(jìn)行線索化 InThreading(p-lchild); / 左子樹(shù)線索化 if (!p-lchild) / 建前驅(qū)線索 p-LTag = Thread; p-lchild = pre; if (!pre-rchild) / 建后繼線索 pre-RTag = Thread; pre-rchild = p; pre = p; / 保持 pre 指向 p 的前驅(qū) InThreading(p-rchild); / 右子樹(shù)線索化 / if / InThreadingStatus InOrderThreading(BiThrTree &Thrt, BiThrTree T) / 構(gòu)建中序線索鏈表 if (!(Thrt = (BiThrTree)malloc( sizeof( BiThrNode) exit (OVERFLOW); Thrt-LTag = Link; Thrt-RTag =Thread; Thrt-rchild = Thrt; / 添加頭結(jié)點(diǎn) return OK; / InOrderThreading if (!T) Thrt-lchild = Thrt; else Thrt-lchild = T; pre = Thrt; InThreading(T); pre-rchild = Thrt; / 處理最后一個(gè)結(jié)點(diǎn) pre-RTag = Thread; Thrt-rchild = pre; 6.6 樹(shù)和森林樹(shù)和森林 的表示方法的表示方法6.6.1 樹(shù)的三種存儲(chǔ)結(jié)構(gòu)樹(shù)的三種存儲(chǔ)結(jié)構(gòu)一、一、雙親表示法雙親表示法二、二、孩子鏈表表示法孩子鏈表表示法三、三、樹(shù)的二叉鏈表樹(shù)的二叉鏈表( (孩子孩子- -兄弟)兄弟) 存儲(chǔ)表示法存儲(chǔ)表示法ABCDEFG0 A -11 B 02 C 03 D 04 E 2 5 F 26 G 5r=0n=6data parent一、雙親表示法一、雙親表示法: typedef struct PTNode Elem data; int parent; / 雙親位置域 PTNode; data parent#define MAX_TREE_SIZE 100結(jié)點(diǎn)結(jié)構(gòu)結(jié)點(diǎn)結(jié)構(gòu):C語(yǔ)言的類型描述語(yǔ)言的類型描述: :typedef struct PTNode nodes MAX_TREE_SIZE; int r, n; / 根結(jié)點(diǎn)的位置和結(jié)點(diǎn)個(gè)數(shù) PTree;樹(shù)結(jié)構(gòu)樹(shù)結(jié)構(gòu):ABCDEFG0 A -11 B 02 C 03 D 04 E 25 F 26 G 4r=0n=6 data firstchild 1 2 34 56二、孩子鏈表表示法二、孩子鏈表表示法:typedef struct CTNode int child; struct CTNode *next; *ChildPtr;孩子結(jié)點(diǎn)結(jié)構(gòu)孩子結(jié)點(diǎn)結(jié)構(gòu): child nextC語(yǔ)言的類型描述語(yǔ)言的類型描述: : typedef struct Elem data; ChildPtr firstchild; / 孩子鏈的頭指針 CTBox;雙親結(jié)點(diǎn)結(jié)構(gòu)雙親結(jié)點(diǎn)結(jié)構(gòu) data firstchildtypedef struct CTBox nodesMAX_TREE_SIZE; int n, r; / 結(jié)點(diǎn)數(shù)和根結(jié)點(diǎn)的位置 CTree;樹(shù)結(jié)構(gòu)樹(shù)結(jié)構(gòu):ABCDEFG AB C E D F Groot AB C E D F G 三、樹(shù)的二叉鏈表三、樹(shù)的二叉鏈表 (孩子孩子-兄弟)存儲(chǔ)表示法兄弟)存儲(chǔ)表示法typedef struct CSNode Elem data; struct CSNode *firstchild, *nextsibling; CSNode, *CSTree;C語(yǔ)言的類型描述語(yǔ)言的類型描述: :結(jié)點(diǎn)結(jié)構(gòu)結(jié)點(diǎn)結(jié)構(gòu): firstchild data nextsibling 6.6.2 森林和二叉樹(shù)的轉(zhuǎn)換森林和二叉樹(shù)的轉(zhuǎn)換設(shè)設(shè)森林森林 F = ( T1, T2, , Tn ); T1 = (root,t11, t12, , t1m);二叉樹(shù)二叉樹(shù) B =( LBT, Node(root), RBT ); 由于二叉樹(shù)可以用二叉鏈表表示,為了使一般樹(shù)由于二叉樹(shù)可以用二叉鏈表表示,為了使一般樹(shù)也能用二叉鏈表表示,必須找出樹(shù)與二叉樹(shù)之間的關(guān)也能用二叉鏈表表示,必須找出樹(shù)與二叉樹(shù)之間的關(guān)系。系。 這樣,給定一棵樹(shù),可以找到唯一的一棵二叉這樣,給定一棵樹(shù),可以找到唯一的一棵二叉樹(shù)與之對(duì)應(yīng)。樹(shù)與之對(duì)應(yīng)。方法:方法: 對(duì)每個(gè)孩子進(jìn)行從左到右的排序;對(duì)每個(gè)孩子進(jìn)行從左到右的排序; 在兄弟之間加一條連線;在兄弟之間加一條連線; 對(duì)每個(gè)結(jié)點(diǎn),除了左孩子外,去除其與其余孩對(duì)每個(gè)結(jié)點(diǎn),除了左孩子外,去除其與其余孩子之間的聯(lián)系;子之間的聯(lián)系; 以根結(jié)點(diǎn)為軸心,將整個(gè)樹(shù)順時(shí)針轉(zhuǎn)以根結(jié)點(diǎn)為軸心,將整個(gè)樹(shù)順時(shí)針轉(zhuǎn)45度。度。1、將樹(shù)轉(zhuǎn)換成二叉樹(shù)、將樹(shù)轉(zhuǎn)換成二叉樹(shù)的轉(zhuǎn)換規(guī)則為: I A B C DE F G H(b) A B CD E G H FI(a)樹(shù)轉(zhuǎn)換為二叉樹(shù)樹(shù)轉(zhuǎn)換為二叉樹(shù)ABEFCDGHI(d)ABCDEFGHI(c)2、由森林轉(zhuǎn)換成二叉樹(shù)、由森林轉(zhuǎn)換成二叉樹(shù)的轉(zhuǎn)換規(guī)則為:若 F = ,則 B = ;否則, 由 ROOT( T1 ) 對(duì)應(yīng)得到 Node(root); 由 (t11, t12, , t1m ) 對(duì)應(yīng)得到 LBT; 由 (T2, T3, Tn ) 對(duì)應(yīng)得到 RBT。森林轉(zhuǎn)換為二叉樹(shù)森林轉(zhuǎn)換為二叉樹(shù)ADCBEFHIGJEFADCBHIGJADCBEFHIGJADCBEFHIGJ3、由二叉樹(shù)轉(zhuǎn)換為森林、由二叉樹(shù)轉(zhuǎn)換為森林的轉(zhuǎn)換規(guī)則為:若 B = , 則 F = ;否則,由 Node(root) 對(duì)應(yīng)得到 ROOT( T1 );由LBT 對(duì)應(yīng)得到 ( t11, t12, ,t1m);由RBT 對(duì)應(yīng)得到 (T2, T3, , Tn)。將二叉樹(shù)轉(zhuǎn)換成樹(shù)或森林的方法如下:將二叉樹(shù)轉(zhuǎn)換成樹(shù)或森林的方法如下:1.若某結(jié)點(diǎn)是其若某結(jié)點(diǎn)是其雙親的雙親的左孩子左孩子,則把該結(jié)點(diǎn)的右孩子、則把該結(jié)點(diǎn)的右孩子、右孩子的右孩子右孩子的右孩子都與該結(jié)點(diǎn)的都與該結(jié)點(diǎn)的雙親雙親結(jié)點(diǎn)用線連起結(jié)點(diǎn)用線連起來(lái)來(lái);2.刪除原二叉樹(shù)中所有的雙親結(jié)點(diǎn)與右孩子結(jié)點(diǎn)的連刪除原二叉樹(shù)中所有的雙親結(jié)點(diǎn)與右孩子結(jié)點(diǎn)的連線線.3.整理步驟整理步驟1、2所得到的樹(shù)或森林所得到的樹(shù)或森林,使結(jié)構(gòu)層次分明使結(jié)構(gòu)層次分明.將二叉樹(shù)轉(zhuǎn)換為樹(shù)或森林的另一種描述:將二叉樹(shù)轉(zhuǎn)換為樹(shù)或森林的另一種描述:ABEFCDGHI(a)ABEFCDGHI(b)將二叉樹(shù)轉(zhuǎn)換為樹(shù)或森林將二叉樹(shù)轉(zhuǎn)換為樹(shù)或森林ABEFCDGHI(c) 若某結(jié)點(diǎn)是其若某結(jié)點(diǎn)是其雙親雙親的的左孩子左孩子,則把該則把該結(jié)點(diǎn)的右孩子、右結(jié)點(diǎn)的右孩子、右孩子的右孩子孩子的右孩子都都與該結(jié)點(diǎn)的與該結(jié)點(diǎn)的雙親雙親結(jié)結(jié)點(diǎn)用線連起來(lái)點(diǎn)用線連起來(lái);刪除原二叉樹(shù)中所刪除原二叉樹(shù)中所有的雙親結(jié)點(diǎn)與右有的雙親結(jié)點(diǎn)與右孩子結(jié)點(diǎn)的連線孩子結(jié)點(diǎn)的連線. 由此,樹(shù)的各種操作均可對(duì)應(yīng)二叉樹(shù)的操作來(lái)完成。 應(yīng)當(dāng)注意的是,應(yīng)當(dāng)注意的是,和樹(shù)對(duì)應(yīng)的二叉樹(shù),其左、右子樹(shù)的概念已改變?yōu)椋?左是孩子,右是兄弟。左是孩子,右是兄弟。6.7樹(shù)和森林的遍歷樹(shù)和森林的遍歷一、樹(shù)的遍歷一、樹(shù)的遍歷二、森林的遍歷二、森林的遍歷三、樹(shù)的遍歷的應(yīng)用三、樹(shù)的遍歷的應(yīng)用樹(shù)的遍歷可有三條搜索路徑樹(shù)的遍歷可有三條搜索路徑:按層次遍歷按層次遍歷:先根先根(次序次序)遍歷遍歷:后根后根(次序次序)遍歷遍歷: 若樹(shù)不空,則先訪問(wèn)根結(jié)點(diǎn),然后若樹(shù)不空,則先訪問(wèn)根結(jié)點(diǎn),然后依次先根遍歷各棵子樹(shù)。依次先根遍歷各棵子樹(shù)。 若樹(shù)不空,則先依次后根遍歷各棵若樹(shù)不空,則先依次后根遍歷各棵子樹(shù),然后訪問(wèn)根結(jié)點(diǎn)。子樹(shù),然后訪問(wèn)根結(jié)點(diǎn)。 若樹(shù)不空,則自上而下自左至右若樹(shù)不空,則自上而下自左至右訪問(wèn)樹(shù)中每個(gè)結(jié)點(diǎn)。訪問(wèn)樹(shù)中每個(gè)結(jié)點(diǎn)。 A B C DE F G H I J K 先根遍歷時(shí)頂點(diǎn)先根遍歷時(shí)頂點(diǎn)的訪問(wèn)次序:的訪問(wèn)次序:A B E F C D G H I J K 后根遍歷時(shí)頂點(diǎn)后根遍歷時(shí)頂點(diǎn)的訪問(wèn)次序:的訪問(wèn)次序:E F B C I J K H G D A 層次遍歷時(shí)頂點(diǎn)層次遍歷時(shí)頂點(diǎn)的訪問(wèn)次序:的訪問(wèn)次序:A B C D E F G H I J K B C DE F G H I J K1森林中第一棵樹(shù)的根結(jié)點(diǎn);2森林中第一棵樹(shù)的子樹(shù)森林;3森林中其它樹(shù)構(gòu)成的森林。森林由三部分構(gòu)成: 若森林不空,則訪問(wèn)訪問(wèn)森林中第一棵樹(shù)的根結(jié)點(diǎn);先序遍歷先序遍歷森林中第一棵樹(shù)的子樹(shù)森林;先序遍歷先序遍歷森林中(除第一棵樹(shù)之外)其 余樹(shù)構(gòu)成的森林。1. 先序遍歷先序遍歷森林的遍歷森林的遍歷即:依次從左至右依次從左至右對(duì)森林中的每一棵樹(shù)樹(shù)進(jìn)行先根遍歷先根遍歷。中序遍歷中序遍歷 若森林不空,則中序遍歷中序遍歷森林中第一棵樹(shù)的子樹(shù)森林;訪問(wèn)訪問(wèn)森林中第一棵樹(shù)的根結(jié)點(diǎn);中序遍歷中序遍歷森林中(除第一棵樹(shù)之外)其 余樹(shù)構(gòu)成的森林。即:依次從左至右依次從左至右對(duì)森林中的每一棵樹(shù)樹(shù)進(jìn)行后根遍歷后根遍歷。 樹(shù)的遍歷和二叉樹(shù)遍歷樹(shù)的遍歷和二叉樹(shù)遍歷的對(duì)應(yīng)關(guān)系的對(duì)應(yīng)關(guān)系 ?先根遍歷先根遍歷后根遍歷后根遍歷樹(shù)樹(shù)二叉樹(shù)二叉樹(shù)森林森林先序遍歷先序遍歷先序遍歷先序遍歷中序遍歷中序遍歷中序遍歷中序遍歷設(shè)樹(shù)的存儲(chǔ)結(jié)構(gòu)為孩子兄弟鏈表設(shè)樹(shù)的存儲(chǔ)結(jié)構(gòu)為孩子兄弟鏈表typedef struct CSNode Elem data; struct CSNode *firstchild, *nextsibling; CSNode, *CSTree;一、求樹(shù)的深度一、求樹(shù)的深度二、輸出樹(shù)中所有從根到葉子的路徑二、輸出樹(shù)中所有從根到葉子的路徑三、建樹(shù)的存儲(chǔ)結(jié)構(gòu)三、建樹(shù)的存儲(chǔ)結(jié)構(gòu)int TreeDepth(CSTree T) if(!T) return 0; else h1 = TreeDepth( T-firstchild ); h2 = TreeDepth( T-nextsibling); / TreeDepthreturn(max(h1+1, h2);一、求樹(shù)的深度的算法:一、求樹(shù)的深度的算法:二、二、輸出樹(shù)中所有從根到葉子的路徑的算法輸出樹(shù)中所有從根到葉子的路徑的算法: A B C DE F G H I J K例如:對(duì)左圖所示的樹(shù),其輸出結(jié)果應(yīng)為:A B EA B FA CA D G H IA D G H JA D G H Kvoid 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ù)上從根到所有葉子結(jié)點(diǎn)的路徑輸出二叉樹(shù)上從根到所有葉子結(jié)點(diǎn)的路徑void OutPath( Bitree T, Stack& S ) while ( !T ) Push(S, T-data ); if ( !T-firstchild ) Printstack(s); else OutPath( T-firstchild, s ); Pop(S); T = T-nextsibling; / while / OutPath/ 輸出森林中所有從根到葉的路徑三、建樹(shù)的存儲(chǔ)結(jié)構(gòu)的算法三、建樹(shù)的存儲(chǔ)結(jié)構(gòu)的算法: 和二叉樹(shù)類似,不同的定義相應(yīng)有不同的算法。 假設(shè)以二元組(F,C)的形式自上而自上而下下、自左而右自左而右依次輸入樹(shù)的各邊,建立樹(shù)的孩子孩子-兄弟鏈表兄弟鏈表。ABCDEFG例如例如:對(duì)下列所示樹(shù)的輸入序列應(yīng)為:(#, A)(A, B)(A, C)(A, D)(C, E)(C, F)(E, G)ABCD(#, A)(A, B)(A, C)(A, D)(C, E)可見(jiàn),算法中需要一個(gè)隊(duì)列隊(duì)列保存已建好的結(jié)點(diǎn)的指針。指針。void CreatTree( CSTree &T ) T = NULL; for( scanf(&fa, &ch); ch!= ; scanf(&fa, &ch);) p = GetTreeNode(ch); / 創(chuàng)建結(jié)點(diǎn)EnQueue(Q, p); / 指針入隊(duì)列if (fa = ) T = p; / 所建為根結(jié)點(diǎn) else / 非根結(jié)點(diǎn)的情況 / for / CreateTree GetHead(Q,s); / 取隊(duì)列頭元素(指針值)while (s-data != fa ) / 查詢雙親結(jié)點(diǎn) DeQueue(Q,s); GetHead(Q,s); if (!(s-firstchild) s-firstchild = p; r = p; / 鏈接第一個(gè)孩子結(jié)點(diǎn)else r-nextsibling = p; r = p; / 鏈接其它孩子結(jié)點(diǎn) 6.8 哈哈 夫夫 曼曼 樹(shù)樹(shù) 與與 哈哈 夫夫 曼曼 編編 碼碼 最優(yōu)樹(shù)的定義最優(yōu)樹(shù)的定義 如何構(gòu)造最優(yōu)樹(shù)如何構(gòu)造最優(yōu)樹(shù) 前綴編碼前綴編碼 一、最優(yōu)樹(shù)的定義一、最優(yōu)樹(shù)的定義樹(shù)的路徑長(zhǎng)度樹(shù)的路徑長(zhǎng)度定義為: 樹(shù)中每個(gè)結(jié)點(diǎn)的路徑長(zhǎng)度之和。 結(jié)點(diǎn)的路徑長(zhǎng)度結(jié)點(diǎn)的路徑長(zhǎng)度定義為: 從根結(jié)點(diǎn)到該結(jié)點(diǎn)的路徑上 分支的數(shù)目。1 12 2453 367PL=0+1+1+2+2+2+2=10樹(shù)的路徑長(zhǎng)度用樹(shù)的路徑長(zhǎng)度用PLPL表示。表示。1 12 245C67PL=0+1+1+2+2+3+3=12 樹(shù)的帶權(quán)路徑長(zhǎng)度樹(shù)的帶權(quán)路徑長(zhǎng)度定義為: 樹(shù)中所有葉子結(jié)點(diǎn)的帶權(quán)路徑長(zhǎng)度結(jié)點(diǎn)的帶權(quán)路徑長(zhǎng)度之和 WPL(T) = wklk (對(duì)所有葉子結(jié)點(diǎn))。其中其中:Wk為樹(shù)中每個(gè)葉子結(jié)點(diǎn)的權(quán); Lk為每個(gè)葉子結(jié)點(diǎn)到根的路徑長(zhǎng)度。例如:例如:27 9 75492WPL(T)= 72+52+23+43+92 =60WPL(T)= 74+94+53+42+21 =89 54最優(yōu)樹(shù)最優(yōu)樹(shù) 在所有含 n 個(gè)葉子結(jié)點(diǎn)、并帶相同權(quán)值的 m 叉樹(shù)中,必存在一棵其帶權(quán)路徑長(zhǎng)度取最小值帶權(quán)路徑長(zhǎng)度取最小值的樹(shù),稱為“最優(yōu)樹(shù)最優(yōu)樹(shù)”。 由原始數(shù)據(jù)生成森林由原始數(shù)據(jù)生成森林 根據(jù)給定的n個(gè)權(quán)值 w1, w2, , wn, 構(gòu)造 n 棵二叉樹(shù)的集合 F = T1, T2, , Tn, 其中每棵二叉樹(shù)中均只含一個(gè)帶權(quán)值 為 wi 的根結(jié)點(diǎn),其左、右子樹(shù)為空樹(shù);二、如何構(gòu)造最優(yōu)樹(shù)二、如何構(gòu)造最優(yōu)樹(shù)(1)(赫夫曼算法) 以二叉樹(shù)為例: 在 F 中選取其根結(jié)點(diǎn)的權(quán)值為最 小的兩棵二叉樹(shù),分別作為左、 右子樹(shù)構(gòu)造一棵新的二叉樹(shù),并 置這棵新的二叉樹(shù)根結(jié)點(diǎn)的權(quán)值 為其左、右子樹(shù)根結(jié)點(diǎn)的權(quán)值之 和;(2) 從F中刪去這兩棵樹(shù),同時(shí)加入 剛生成的新樹(shù); 重復(fù) (2) 和 (3) 兩步,直至 F 中只 含一棵樹(shù)為止。(3)(4)675cd(b)11b57cd(c)18a711cdb5624(d)abcd7524(a)例:給定權(quán)值例:給定權(quán)值77,5 5,2 2,44,構(gòu)造赫夫曼樹(shù)。構(gòu)造赫夫曼樹(shù)。9例例: : 已知權(quán)值已知權(quán)值 W= 5, 6, 2, 9, 7 ,構(gòu)造赫夫曼樹(shù)。構(gòu)造赫夫曼樹(shù)。5627527697671395276713952795271667132900001111000110110111三、哈夫曼樹(shù)的應(yīng)用三、哈夫曼樹(shù)的應(yīng)用1 1、判定樹(shù)、判定樹(shù) 在解決某些判定問(wèn)題時(shí),利用哈夫曼樹(shù)可以得在解決某些判定問(wèn)題時(shí),利用哈夫曼樹(shù)可以得到最佳判定算法。到最佳判定算法。例例1 將學(xué)生百分成績(jī)按分?jǐn)?shù)段分級(jí)的程序。將學(xué)生百分成績(jī)按分?jǐn)?shù)段分級(jí)的程序。若學(xué)生成績(jī)分布是均勻的,可用圖(若學(xué)生成績(jī)分布是均勻的,可用圖(a)二叉樹(shù)結(jié)構(gòu)二叉樹(shù)結(jié)構(gòu)來(lái)實(shí)現(xiàn)。來(lái)實(shí)現(xiàn)。 a60 a70 a80 a90 不及格不及格中等中等良好良好優(yōu)秀優(yōu)秀及格及格YNYNYNYN(a)輸入輸入10000個(gè)個(gè)數(shù)據(jù),則需進(jìn)數(shù)據(jù),則需進(jìn)行行31500次比次比較。較。分?jǐn)?shù)分?jǐn)?shù)0596069707980899099比例比例0.050.150.40.30.10 70a 80 a60 及格及格中等中等良好良好 80a90 60a70 不及格不及格優(yōu)秀優(yōu)秀YNYYYNNN(b) 不及格不及格Y a90 a80 a70 a60 優(yōu)秀優(yōu)秀中等中等及格及格良好良好YNNN(c)YYY 學(xué)生成績(jī)分布不是均勻的情況:學(xué)生成績(jī)分布不是均勻的情況:以比例數(shù)為權(quán)構(gòu)造一棵哈夫曼樹(shù),以比例數(shù)為權(quán)構(gòu)造一棵哈夫曼樹(shù),如(如(b)判斷樹(shù)所示。判斷樹(shù)所示。再將每一比較框的兩次比較改為一再將每一比較框的兩次比較改為一次,可得到(次,可得到(c)判定樹(shù)。判定樹(shù)。輸入輸入10000個(gè)個(gè)數(shù)據(jù),僅需進(jìn)數(shù)據(jù),僅需進(jìn)行行22000次比次比較。較。2 2、前綴編碼、前綴編碼 “前綴編碼”指的是,任何一個(gè)字符任何一個(gè)字符的編碼都不是同一字符集中另一個(gè)字符的編碼都不是同一字符集中另一個(gè)字符的編碼的前綴的編碼的前綴。3 3、赫夫曼編碼、赫夫曼編碼 利用赫夫曼樹(shù)可以構(gòu)造一種不等長(zhǎng)的利用赫夫曼樹(shù)可以構(gòu)造一種不等長(zhǎng)的二進(jìn)制編碼,并且構(gòu)造所得的二進(jìn)制編碼,并且構(gòu)造所得的赫夫曼編碼赫夫曼編碼是一種是一種最優(yōu)前綴編碼最優(yōu)前綴編碼,即使所傳,即使所傳電文的總電文的總長(zhǎng)度最短長(zhǎng)度最短。146833442200001111T;ACS各字符編碼是各字符編碼是 T ; A C S 00 01 10 110 111上述電文編碼:上述電文編碼:11010111011101000011111000011000方法:方法:(1)用)用 2,4, 2,3, 3 作為葉子結(jié)點(diǎn)的權(quán)值生成一棵赫作為葉子結(jié)點(diǎn)的權(quán)值生成一棵赫夫曼樹(shù),并將對(duì)應(yīng)權(quán)值夫曼樹(shù),并將對(duì)應(yīng)權(quán)值wi的葉子結(jié)點(diǎn)注明對(duì)應(yīng)的字符;的葉子結(jié)點(diǎn)注明對(duì)應(yīng)的字符;(2)約定左分支表示字符)約定左分支表示字符“0”,右分支表示字符,右分支表示字符1(3)從葉子結(jié)點(diǎn)開(kāi)始,順著雙親反推上去,直到根結(jié)點(diǎn),路)從葉子結(jié)點(diǎn)開(kāi)始,順著雙親反推上去,直到根結(jié)點(diǎn),路徑上的徑上的0或或1連接的序列就是結(jié)點(diǎn)對(duì)應(yīng)的字符的二進(jìn)制連接的序列就是結(jié)點(diǎn)對(duì)應(yīng)的字符的二進(jìn)制編碼的編碼的逆序逆序。赫夫曼編碼赫夫曼編碼-利用赫夫曼樹(shù)構(gòu)造通訊中電文編碼(前綴碼)利用赫夫曼樹(shù)構(gòu)造通訊中電文編碼(前綴碼)例:例:要傳輸?shù)碾娢氖且獋鬏數(shù)碾娢氖荂AS;CAT;SAT;AT要傳輸?shù)淖址且獋鬏數(shù)淖址?D=C,A,S,T, ;每個(gè)字符出現(xiàn)的頻率是每個(gè)字符出現(xiàn)的頻率是W= 2,4, 2,3, 3 注意:編碼的總長(zhǎng)度恰好為赫夫曼樹(shù)的帶權(quán)路徑長(zhǎng)。注意:編碼的總長(zhǎng)度恰好為赫夫曼樹(shù)的帶權(quán)路徑長(zhǎng)。構(gòu)造赫夫曼樹(shù)的算法構(gòu)造赫夫曼樹(shù)的算法 為了實(shí)現(xiàn)構(gòu)造赫夫曼樹(shù)的算法為了實(shí)現(xiàn)構(gòu)造赫夫曼樹(shù)的算法,設(shè)計(jì)哈夫曼樹(shù)中每個(gè)設(shè)計(jì)哈夫曼樹(shù)中每個(gè)結(jié)點(diǎn)類型如下:結(jié)點(diǎn)類型如下: typedef struct char data;/*結(jié)點(diǎn)值結(jié)點(diǎn)值*/float weight;/*權(quán)重權(quán)重*/int parent;/*雙親結(jié)點(diǎn)雙親結(jié)點(diǎn)*/int lchild;/*左孩子結(jié)點(diǎn)左孩子結(jié)點(diǎn)*/int rchild;/*右孩子結(jié)點(diǎn)右孩子結(jié)點(diǎn)*/ HTNode,* HuffmanTree;

注意事項(xiàng)

本文(數(shù)據(jù)結(jié)構(gòu)嚴(yán)蔚敏第6章)為本站會(huì)員(仙***)主動(dòng)上傳,裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)上載內(nèi)容本身不做任何修改或編輯。 若此文所含內(nèi)容侵犯了您的版權(quán)或隱私,請(qǐng)立即通知裝配圖網(wǎng)(點(diǎn)擊聯(lián)系客服),我們立即給予刪除!

溫馨提示:如果因?yàn)榫W(wǎng)速或其他原因下載失敗請(qǐng)重新下載,重復(fù)下載不扣分。




關(guān)于我們 - 網(wǎng)站聲明 - 網(wǎng)站地圖 - 資源地圖 - 友情鏈接 - 網(wǎng)站客服 - 聯(lián)系我們

copyright@ 2023-2025  zhuangpeitu.com 裝配圖網(wǎng)版權(quán)所有   聯(lián)系電話:18123376007

備案號(hào):ICP2024067431號(hào)-1 川公網(wǎng)安備51140202000466號(hào)


本站為文檔C2C交易模式,即用戶上傳的文檔直接被用戶下載,本站只是中間服務(wù)平臺(tái),本站所有文檔下載所得的收益歸上傳人(含作者)所有。裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)上載內(nèi)容本身不做任何修改或編輯。若文檔所含內(nèi)容侵犯了您的版權(quán)或隱私,請(qǐng)立即通知裝配圖網(wǎng),我們立即給予刪除!