版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1一、雙親表示法二、孩子鏈表表示法三、樹的二叉鏈表(孩子-兄弟)存儲表示法6.4樹和森林6.4.1樹的存儲結(jié)構(gòu)2一、雙親表示法(順序存儲)
用一組連續(xù)空間存儲樹的結(jié)點(diǎn),同時在每個結(jié)點(diǎn)中附設(shè)一個域指示其雙親的位置。aedbihgcf021345678dataparent
0a-11b02
c03d14e15f26g47h4
8i43
typedefstructPTNode{Elemdata;
intparent;//雙親位置域
}PTNode;#defineMAX_TREE_SIZE100結(jié)點(diǎn)結(jié)構(gòu):C語言的類型描述:
dataparent4typedefstruct{PTNodenodes[MAX_TREE_SIZE];
intr,n;//根結(jié)點(diǎn)的位置和結(jié)點(diǎn)個數(shù)
}PTree;樹結(jié)構(gòu):5(1)由于樹中每個結(jié)點(diǎn)可有多個孩子,則每個結(jié)點(diǎn)可設(shè)多個指針成員,每個指針指向一個孩子。對于度為m的樹,結(jié)點(diǎn)結(jié)構(gòu)如下:datadegree
c1c2
…ckdatac1c2c3
…cm(2)每個結(jié)點(diǎn)有幾個孩子,就有幾個指針。二、孩子表示法(鏈?zhǔn)酱鎯Γ﹩栴}:會有太多的空指針!(3)將每個結(jié)點(diǎn)的孩子結(jié)點(diǎn)排列起來,連接成一個單鏈表。n個結(jié)點(diǎn)有n個孩子鏈表,n個孩子鏈表的頭指針可放在數(shù)組中,稱為孩子鏈表。60a12
1b342c53d4e6785f6g7h8i孩子鏈表aedbihgcf0213456787typedefstructCTNode{
intchild;
structCTNode*nextchild;}*ChildPtr;孩子結(jié)點(diǎn)結(jié)構(gòu):
childnextchildC語言的類型描述:8
typedefstruct{Elemdata;ChildPtrfirstchild;//孩子鏈的頭指針}CTBox;雙親結(jié)點(diǎn)結(jié)構(gòu)
datafirstchildtypedefstruct{CTBoxnodes[MAX_TREE_SIZE];
intn,r;//結(jié)點(diǎn)數(shù)和根結(jié)點(diǎn)的位置
}CTree;樹結(jié)構(gòu):帶雙親的孩子鏈表:將雙親表示法和孩子表示法結(jié)合起來。aedbihgcf0
a-112
1b0342c053d14e16785f26g47h48i4021345678三、孩子兄弟表示法:又稱樹的二叉鏈表表示法即用二叉鏈表作樹的存儲結(jié)構(gòu)。結(jié)點(diǎn)中的兩個指針分別指向該結(jié)點(diǎn)的第一個孩子和下一個兄弟aedbihgcf
a
b
c
d
e
f
g
h
i
11typedefstructCSNode{Elemdata;
structCSNode*firstchild,*nextsibling;}CSNode,*CSTree;C語言的類型描述:結(jié)點(diǎn)結(jié)構(gòu):
firstchilddatanextsibling12ABCDEFGrootABCEDFGABCEDFG
畫出以下存儲結(jié)構(gòu)root13樹ABCED二叉樹ABCEDA^BCDE^^^^^6.4.2森林與二叉樹的轉(zhuǎn)換
從樹的鏈表表示的定義可知,任何一棵與樹對應(yīng)的二叉樹,其右子樹必空。若把森林中第二棵樹的根結(jié)點(diǎn)看成是第一棵樹的根結(jié)點(diǎn)的兄弟,則可導(dǎo)出森林和二叉樹的關(guān)系。森林
二叉樹ABCDEFGHIJABCFEGDIHJ15森林與二叉樹互相轉(zhuǎn)換的方法:一.森林轉(zhuǎn)換成二叉樹①將森林中的每棵樹轉(zhuǎn)換為二叉樹;②將第i+1棵樹作為第i棵樹的右子樹,依次連接成一棵二叉樹;二.二叉樹轉(zhuǎn)換成森林①將二叉樹根的右子樹作為另一棵二叉樹,將新分出的二叉樹轉(zhuǎn)換成森林;②將二叉樹轉(zhuǎn)換成森林;1247356891016
樹的遍歷1.按層次:先訪問第一層的結(jié)點(diǎn),之后訪問第二層的結(jié)點(diǎn)。2.先根遍歷:先訪問根結(jié)點(diǎn),依次先根遍歷其各子樹。3.后根遍歷:依次后根遍歷其各子樹,再訪問根結(jié)點(diǎn)。6.4.3樹和森林的遍歷17
樹先根:ABEFCGIJD
后根:EFBIGJCDA二叉樹先序遍歷中序遍歷ABCFEGDJIABCFEGDJI181.森林中第一棵樹的根結(jié)點(diǎn);2.森林中第一棵樹的子樹森林;3.森林中其它樹構(gòu)成的森林??梢苑纸獬扇糠?森林BCDEFGHIJK森林的遍歷19若森林不空,則訪問森林中第一棵樹的根結(jié)點(diǎn);先序遍歷森林中第一棵樹的子樹森林;先序遍歷森林中(除第一棵樹之外)其余樹構(gòu)成的森林。先序遍歷即:依次從左至右對森林中的每一棵樹進(jìn)行先根遍歷。20
中序遍歷
若森林不空,則中序遍歷森林中第一棵樹的子樹森林;訪問森林中第一棵樹的根結(jié)點(diǎn);中序遍歷森林中(除第一棵樹之外)其余樹構(gòu)成的森林。即:依次從左至右對森林中的每一棵樹進(jìn)行后根遍歷。例如:先序遍歷:ABCDEFGHIJ中序遍歷:BCDAFEHJIG結(jié)論:二叉樹森林先序遍歷先序遍歷中序遍歷中序遍歷ABCDEFGHIJABCFEGDIHJ22設(shè)樹的存儲結(jié)構(gòu)為孩子兄弟鏈表typedefstructCSNode{Elemdata;
structCSNode*firstchild,*nextsibling;}CSNode,*CSTree;一、建樹的存儲結(jié)構(gòu)二、先序遍歷樹(森林)三、求樹(森林)的深度四、輸出樹中所有從根到葉子的路徑一、建樹的存儲結(jié)構(gòu)的算法:
和二叉樹類似,不同的定義相應(yīng)有不同的算法。
假設(shè)以二元組(F,C)的形式自上而下、自左而右依次輸入樹的各邊,建立樹的孩子-兄弟鏈表。ABCDEFG例如:對下列所示樹的輸入序列應(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’)可見,算法中需要一個隊(duì)列保存已建好的結(jié)點(diǎn)的指針voidCreatTree(CSTree&T){T=NULL;
for(scanf(&fa,&ch);ch!=
;
scanf(&fa,&ch);){ p=New
CSNode;
p->data=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;}
//鏈接第一個孩子結(jié)點(diǎn)else
{r->nextsibling=p;r=p;}
//鏈接其它孩子結(jié)點(diǎn)
27ABCEDA^BCDE^^^^^二、先序遍歷樹(森林)的遞歸算法:28voidpre_order_tree(CSTreeT){
for(p=T;p;p=p→nextsibling){printf(p→data);
if(p→firstchild≠NULL)pre_order_tree(p→firstchild);
}}//preorder遞歸算法:29voidOutPath(BitreeT){
while(T){printf(p→data);
if(T->firstchild)
OutPath(T->firstchild);
T=T->nextsibling;
}//while}//OutPath//while循環(huán)寫的遍歷算法30ABCEDA^BCDE^^^^^三、求樹的深度的算法:31intDepth(CSTreeT){if(T==NULL)return0;else{d1=Depth(T->firstchild);d2=Depth(T->nextsibling);returnmax(d1+1,d2)}三、求樹的深度的算法:32四、輸出樹中所有從根到葉子的路徑的算法:ABCDEFGHIJK例如:對左圖所示的樹,其輸出結(jié)果應(yīng)為:ABEABFACADGHIADGHJADGHK33voidOutPath(BitreeT){
while(T){printf(p→data);
if(T->firstchild)
OutPath(T->firstchild);
T=T->nextsibling;
}//while}//OutPath//原有遍歷算法34voidOutPath(BitreeT,Stack*S){
while(T){
Push(*S,T->data);
if(!T->firstchild)Printstack(*S);
elseOutPath(T->firstchild,S);
Pop(*S);
T=T->nextsibling;
}//while}//OutPath//輸出森林中所有從根到葉的路徑3536互聯(lián)網(wǎng)上的域名如同我們現(xiàn)實(shí)生活中的門牌號碼,可以在紛繁蕪雜的網(wǎng)絡(luò)世界里準(zhǔn)確無誤地把我們指引到我們要訪問的站點(diǎn)。37結(jié)點(diǎn)間的路徑長度:
兩個結(jié)點(diǎn)之間的分支數(shù)。結(jié)點(diǎn)的權(quán)值:
附加在結(jié)點(diǎn)上的信息。結(jié)點(diǎn)帶權(quán)路徑:
結(jié)點(diǎn)上權(quán)值與該結(jié)點(diǎn)到根之間的路徑長度的乘積。6.5哈夫曼樹及其應(yīng)用6.5.1最優(yōu)二叉樹——哈夫曼樹ABCDEFGHIJ38樹的帶權(quán)路徑長度:
(WeightPathLength)
樹中所有葉子結(jié)點(diǎn)的帶權(quán)路徑長度之和。WPL=(葉到根的平均路徑長度)哈夫曼(huffman)樹:使WPL取最小值的二叉樹,又稱最優(yōu)二叉樹ABCDEFGHIJ203050例:有n個葉子結(jié)點(diǎn),第i個葉子結(jié)點(diǎn)的權(quán)值為Wi,根到該結(jié)點(diǎn)的路徑長度為Li,則:39例如,給定權(quán)值{5,4,7,2,5},可生成多棵二叉樹WPL=2*1+7*3+4*3+5*3+5*3=6557254(a)57254(b)WPL=2*1+4*2+5*3+7*4+5*4=7340WPL=(2+4)*3+(7+5+5)*2=52WPL=(5+5+7)*2+(2+4)*3=5257254(c)57254(d)41如何構(gòu)成一棵最優(yōu)二叉樹?
(哈夫曼算法)
(1)根據(jù)n個權(quán)值{w1,w2,…,wn}構(gòu)成n棵二叉樹的集合F={T1,T2,…,Tn},其中每棵二叉樹Ti只有一個帶權(quán)為Wi的根結(jié)點(diǎn),其左右子樹均空。(2)在F中選兩棵根結(jié)點(diǎn)的權(quán)值最小的樹作為左右子樹構(gòu)成一棵新的二叉樹,且根結(jié)點(diǎn)的權(quán)值為其左右子樹根結(jié)點(diǎn)的權(quán)值之和。(3)在F中刪除這兩棵樹,同時將新的二叉樹加入F(4)重復(fù)(2)、(3),直到F只含一棵樹為止。9例如:已知權(quán)值W={5,6,2,9,7}5627257697671392576713925792571667132944哈夫曼樹的應(yīng)用:在解決某些判定問題時的最佳判定算法。例:將學(xué)生百分成績按分?jǐn)?shù)段分級的程序。若學(xué)生成績分布是均勻的,可用二叉樹結(jié)構(gòu)來實(shí)現(xiàn)。a<60a<70a<80a<90不及格中等良好優(yōu)秀及格YNYNYNYN輸入10000個數(shù)據(jù),則需進(jìn)行28000次比較。讀入一個a值平均判斷:(1+2+3+4+4)*0.2=2.8(次)45分?jǐn)?shù)0—5960—6970—7980—8990—99比例0.050.150.40.30.10學(xué)生成績分布不是均勻的情況:構(gòu)造一棵哈夫曼樹:再將每一比較框的兩次比較改為一次:WPL=0.4*1+0.3*2+0.15*3+(0.05+0.1)*4=2.05WPL=(0.4+0.3+0.1)*2+(0.05+0.15)*3=2.20輸入10000個數(shù)據(jù),僅需進(jìn)行22000次比較。0.40.050.10.150.150.30.30.670≤a<80a<60及格中等良好80≤a<9060≤a<70不及格優(yōu)秀YNYNYNYN
不及格Ya<90a<80a<70a<60優(yōu)秀中等及格良好YNNNYYYN46
哈夫曼編碼是二進(jìn)制編碼形式,用于(網(wǎng)絡(luò))通信中,它作為一種最常用無損壓縮編碼方法,在數(shù)據(jù)壓縮程序中具有非常重要的應(yīng)用。
如需傳送字符串‘ABACCDA’,只有4種字符:A、B、C、D,只需兩位編碼。如分別編碼為00、01、10、11,上述字符串的二進(jìn)制總長度為14位。
在傳送信息時,希望總長度盡可能短,可對每個字符進(jìn)行不等長度的編碼,且出現(xiàn)頻率高的字符編碼盡量短。如A、B、C、D的編碼分別為0、00、1、01時,上述電文長度會縮短,但可能有多種譯法。如‘0000’可能是‘AAAA’,‘ABA’,‘BB’。6.5.2哈夫曼編碼47若要設(shè)計不等長編碼,任一字符的編碼都不是另一個字符編碼的前綴。這種編碼稱為前綴編碼。
可利用二叉樹來設(shè)計二進(jìn)制的前綴編碼,將每個字符出現(xiàn)的頻率作為權(quán),設(shè)計一棵哈夫曼樹,左分支為0,右分之為1,就得到每個葉子結(jié)點(diǎn)的編碼。95271667132900001111000111100101例如:編碼:0、00、1、01就不是前綴編碼。[結(jié)論1]存儲結(jié)構(gòu):#defineN字符數(shù)目;#defineM結(jié)點(diǎn)數(shù)目;//m=2n-1huffman樹用靜態(tài)三叉鏈表做存儲結(jié)構(gòu),且0號單元不用huffman編碼用指向字符的指針數(shù)組來動態(tài)管理存儲;且0號單元不用[證]:m=n0+n1+n2
,因?yàn)椋簄1=0,n2=n0-1,
所以:m=2n0–1,即m=2n-1.huffman樹中沒有度為1的結(jié)點(diǎn)。[結(jié)論2]有n個葉子結(jié)點(diǎn)的huffman樹中共有m=2n-1個結(jié)點(diǎn)。49Data
ABDCENFGI...lchild245070000...rchild306089000...
123456789
FAHDBCGFEI123456789補(bǔ)充:靜態(tài)鏈表存儲typedefstruct{
chardata;
intweight;
intparent,lch,rch;
}NodeType;
//huffman樹結(jié)點(diǎn)類型
typedefchar**HufCode
;
//動態(tài)分配指針數(shù)組存儲huffman編碼typedef
NodeType
HufTree[M+1];
//靜態(tài)三叉鏈表存儲huffman樹1234hcd例:設(shè)有4個結(jié)點(diǎn)a、b、c、d,權(quán)值分別為(0.4,0.3,0.1,0.2)。dataweightparentlchrcha
0.4000
b
0.3000
c
0.1000
d
0.20000.303450.6
0
2561.0016770123456750‘\0’10‘\0’110‘\0’111‘\0’61.0
01
0.4
01
0.3
01
0.10.21.0a0.6b0.3cd算法1:已知n個字符的權(quán)值,生成一棵huffman樹。voidhuff_tree(intw[n],HufTree&ht){//w存放權(quán)值for(i=1;i≤n;i++){//哈夫曼樹初始化ht[i].weight=w[i-1];ht[i].parent=0;ht[i].lch=0;ht[i].rch=0
};ht[n+1..m].parent=0;for(i=n+1;i≤m;i++){
//構(gòu)造n-1個非葉子結(jié)點(diǎn)select(i-1,s1,s2);
//在ht[1..i-1]中選擇兩個雙親為0并且權(quán)值最小的兩個結(jié)點(diǎn),//最小結(jié)點(diǎn)位置為s1,次小的位置為s2。
ht[i].weight=ht[s1].weight+ht[s2].weightht[i].lch=s1;ht[i].rch=s2;
ht[s1].parent=i;ht[s2].parent=i;};}//huff_tree5301234
cd0123dataweightparentlchrcha
0.4000
b
0.3000
c
0.1000
d
0.20000.30
3450.6
0
2561.00
167701234567561234hcd0‘\0’10‘\0’110‘\0’111‘\0’hcdtypedef
char**
HufCode;
//動態(tài)分配指針數(shù)組存儲huffman編碼HufCode
hcd;char*cd;‘\0’start0start
‘\0’0
算法2:由huffman樹求n個字符的haffman編碼voidhuf_code(HufCode
&hcd,HufTree
ht,intn){hcd=(hufcode)malloc((n+1)*sizeof(char*));//指針數(shù)組空間cd=(char*)malloc(n*sizeof(char));//求編碼的臨時空間for(i=1;i≤n;i++){
cd[n-1]=‘\0’;//編碼結(jié)束符
start=n-1;c=i;f=ht[c].parent;
while(f≠0
溫馨提示
- 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 23《海底世界》說課稿-2024-2025學(xué)年三年級下冊語文統(tǒng)編版
- 專項(xiàng)工程造價咨詢修改合同:2024版一
- 2025版高端酒店窗簾制作與安裝合作協(xié)議3篇
- 6 將相和說課稿-2024-2025學(xué)年五年級上冊語文統(tǒng)編版
- 哈姆雷特悲劇情節(jié)讀后感
- 2024淘寶年度合作伙伴產(chǎn)品研發(fā)合同模板3篇
- 2024年股權(quán)收購與債務(wù)重組合同3篇
- 2024年長春婚姻解除合同樣本3篇
- 個人承包2024年度生產(chǎn)線能源管理合同3篇
- 2025年新能源汽車充電樁建設(shè)與運(yùn)營管理合同模板3篇
- 全過程人民民主學(xué)習(xí)心得體會
- 冠心病診斷與治療課件
- 2023年上海期貨交易所招聘筆試題庫及答案解析
- 新疆少數(shù)民族發(fā)展史課件
- 工程監(jiān)理資料移交單
- 全國醫(yī)療服務(wù)價格項(xiàng)目規(guī)范(2012年版)-工作手冊
- 水庫蓄水安全鑒定提供資料要求
- 九月主題計劃《 嗨,你好》
- e乙二醇精制車間設(shè)備布置圖
- 縣級綜治中心等級評定細(xì)則、申報表、負(fù)面清單、流程圖
- 《中外資產(chǎn)評估準(zhǔn)則》課件第1章 資產(chǎn)評估準(zhǔn)則及其形成機(jī)理
評論
0/150
提交評論