第五章 树状结构.docx
- 文档编号:24435991
- 上传时间:2023-05-27
- 格式:DOCX
- 页数:22
- 大小:72.66KB
第五章 树状结构.docx
《第五章 树状结构.docx》由会员分享,可在线阅读,更多相关《第五章 树状结构.docx(22页珍藏版)》请在冰豆网上搜索。
第五章树状结构
第五章樹狀結構
5-1基本觀念
樹狀結構可以用來描述有分支的結構,由一個或一個以上的節點所組成的有限集合,其特質如下:
存在一個特殊的節點,稱為樹根(root),其餘的節點分為
個互斥集合,包括
、
、
…
,每個集合稱為子樹。
如下圖:
A為根節點、B、C及D均為A的子節點
專有名詞介紹:
(1)Root:
無父節點的節點稱為根節點,如A
(2)Parent(父節點):
每一節點的上層節點為父節點,如B的父節點為A。
(3)children(子節點):
每一節點的下層節點為子節點,如B的子節點有E及F。
(4)siblings(兄弟節點):
有共同父節點的節點稱為兄弟節點,如B、C、D之父節點為A,因此彼此為兄弟節點。
(5)degree(分支度):
子樹的個數稱為該節點之分支度,如A的分支度為3,B的分支度為2。
(6)terminalnode(終端節點或樹葉節點):
無子節點的節點,如E、F、C、G。
(7)non-terminalnode(非終端節點):
樹葉以外的節點均為非終端節點,如B、D、A。
(8)level(階層或階度):
A為階層1,B、C、D為階層2,E、F、G為階層3。
(9)height(高度):
樹的最大階度,例如此樹階度為3。
(10)forest:
(11)ancestor和decendent
考題1:
請說明上述專有名詞之涵義與解釋
5-2二元樹(Binarytree)表示法
為何用二元樹?
若取n個鏈結個數為最大固定長度,而每個節點資料結構如下
data
Link1
Link2
…………………………….
linkn
此種n元樹十分浪費鏈結空間,假設此n元樹有m個節點,那此樹共使用n*m個鏈結欄位,同時除數根外,每一個非空鏈結都指向一個節點,得知空鏈結個數為
,而n元樹鏈結浪費率為
,因此可推得各元樹浪費率。
其中二元樹浪費率最少,約1/2,因此一般採用二元樹。
考題2:
為何樹狀結構儲存於資料庫時採用二元樹結構,請說明與推導。
(1)二元樹定義
二元樹最多只有兩個子節點,也就是說分支度小於或等於2。
同時二元樹必須考慮次序關係。
範例:
深度為k的二元樹總節點數最多是
(完滿樹Fullybinarytree),試證明之。
(2)特殊二元樹結構
(A)Fullybinarytree完滿二元樹
(B)Completebinarytree完整二元樹
1.對於完整二元樹而言,此二元樹階層為:
取整數(
)+1
考題3:
請畫出深度4的所有二元樹。
(C)Skewedbinarytree
(D)Strictlybinarytree
(3)採用陣列結構儲存二元樹
將二元樹想像成一個完滿二元樹,並使用一維陣列建立二元樹表示方式及索引值的配置如下圖:
隨後配置索引值如下:
Index
1
2
3
4
5
6
7
content
A
B
C
D
E
同時依據下列規則
小於父節點的值放在左子節點,大於父節點的值放在右子節點,建立下列二元樹程式範例
/*[名稱]:
ch05_01.cpp[示範]:
建立二元樹*/
/*
[名稱]:
ch05_01.cpp
[示範]:
建立二元樹
*/
#include
usingnamespacestd;
intmain()
{
inti,level;
intdata[]={6,3,5,9,7,8,4,2};//原始陣列
intbtree[15]={0};//存放二元數陣列
cout<<"原始陣列內容:
"< for(i=0;i<8;i++) cout<<"["< cout< for(i=0;i<8;i++)//把原始陣列中的值逐一比對 { for(level=1;btree[level]! =0;)//比較樹根及陣列內的值 { //cout<<"btree["< if(data[i]>btree[level])//如果陣列內的值大於樹根,則往右子樹比較 level=level*2+1; else//如果陣列內的值小於或等於樹根,則往左子樹比較 level=level*2; }//如果子樹節點的值不為0,則再與陣列內的值比較一次 btree[level]=data[i];//把陣列值放入二元樹 } cout<<"二元樹內容: "< for(i=1;i<16;i++) cout<<"["< cout< return0; } 考題4: 1.請撰寫一程式,能將陣列資料儲存於二元樹中。 2.請問當有陣列資料數為N時,將其以二元樹方式儲存時,應該要宣告多大的陣列。 Ans: 其資料階層為 ,其完滿二元樹(Fullybinarytree)數量為 ,因此至少要有 個資料筆數,也就是陣列要有 大小才行。 (4)採用鏈結串列儲存二元樹 二元樹之鏈結串列節點宣告如下: LChild Data RChild 指向左子樹節點值指向右子樹 節點宣告如下: structtree { intdata; tree*left; tree*right; }; 5-3二元樹走訪(BinaryTreeTraversal) 所謂走訪就是「拜訪樹中所有的節點各一次」,在走訪後將樹中資料轉換為線性關係。 按照二元樹由左向右的特性,下列二元樹有三種走訪方式。 (1)BAC中序走訪(Inorder) 樹根在中間 上例走訪次序為: DBEACF 採用遞迴演算法為 voidInorder(btreeptr) { if(ptr! =NULL) { Inorder(ptr->left);//printleft cout<<“[“< (2)< Inorder(ptr->right);//printright } } (2)ABC前序走訪(Preorder) 樹根在前面 上例走訪次序為: ABDECF 採用遞迴演算法為 voidPreorder(btreeptr) { if(ptr! =NULL) { cout<<“[“< (2)< Preorder(ptr->left);//printleft Preorder(ptr->right);//printright } } (3)BCA後序走訪(Postorder) 樹根在後面 上例走訪次序為: DEBFCA 採用遞迴演算法為 voidPostorder(btreeptr) { if(ptr! =NULL) { Postorder(ptr->left);//printleft Postorder(ptr->right);//printright cout<<“[“< (2)< } } 考題5: 請說明前序、中序及後序走訪之遞迴演算法? 範例: 請問以下二元樹的中序、前序及後序表示法為何? 中序FDBEHGIAC 前序ABDFEGHIC 後序FDHIGEBCA 考題6: 寫出中序、後序及前序演算法之走訪次序 (4)將數列轉成二元樹 範例: 一樹被表成A(B(CD)E(F(G)H(I(JK)L(MN)))),畫出二元樹結構及前、中及後序走訪結果 (5)二元樹範例程式 範例程式: 建立一程式,指定二元樹內容,並再列印二元樹後把樹的前、中、後序列印出來。 程式碼範例 #include usingstd: : cout; usingstd: : endl; usingstd: : cin; #include usingstd: : setw; structtree { intdata; tree*left; tree*right; }; tree*create_tree(tree*,int); voidpreorder(tree*); voidinorder(tree*); voidpostorder(tree*); intmain() { intarray[]={3,2,4,1,5,6,7,8,9,10,11}; tree*ptr=NULL;//宣告樹根 cout<<"Theoriginalmatrixcontentis"< //Printouttheoriginaldata for(inti=0;i<11;i++) { ptr=create_tree(ptr,array[i]); cout< } cout< cout<<"Thecontentofbinarytree."< cout<<"Sortingbypre-orderis"< preorder(ptr); cout< cout<<"Sortingbyinorderis"< inorder(ptr); cout< cout<<"Sortingbypostorderis"< postorder(ptr); cout< return0; } tree*create_tree(tree*root,intval) { tree*newnode;//declareanewnode tree*current;//declareacurrentnode tree*backup;//declareabackupnode newnode=newtree;//createaspacetosavedata newnode->data=val; newnode->left=NULL; newnode->right=NULL; if(root==NULL)//Firstpointistheroot { root=newnode; returnroot; } else { for(current=root;current! =NULL;) { backup=current;//reservetherootnode if(current->data>val) current=current->left; else current=current->right; } if(backup->data>val) backup->left=newnode; else backup->right=newnode; } returnroot; } voidpreorder(tree*ptr) { if(ptr! =NULL) { cout<<"["< preorder(ptr->left); preorder(ptr->right); } } voidinorder(tree*ptr) { if(ptr! =NULL) { inorder(ptr->left); cout<<"["< inorder(ptr->right); } } voidpostorder(tree*ptr) { if(ptr! =NULL) { postorder(ptr->left); postorder(ptr->right); cout<<"["< } } 考題7: 給一組數據,畫出二元樹,再以中序、後序及前序演算法做出走訪結果。 (6)二元運算樹(BinaryExpressionTree) 定義: 將算術式轉換成二元運算樹 建立規則: (A)考慮算術中運算子(operator)的結合性(associativity)與優先權(priority),再適當的加上括號。 (B)由最內層括號逐步向外,利用運算子當樹根,左邊運算元當左子樹,右邊運算元當右子樹,其中優先權最低的運算子做為此二元運算樹的樹根。 範例1: A–B*(-C+(-3.5)) Step1.加括號 (A–(B*((-C)+(-3.5)))) Step2.做出二元運算樹 Step3.各種表示法 前序表示法-A*B+-C-3.5 中序表示法A-B*-C+-3.5 後序表示法ABC-3.5-+*- 範例: 請將A/B**C+D*E-A*C化為二元樹: Step1.加括號 (((A/(B**C)+(D*E))-(A*C)) 考題8: 給一組運算式,然後畫出二元樹,並以走訪方式說出前序、中序及後序走訪結果。 1.4二元樹進階研究 (1)二元樹排序 二元樹為一種很好的排序模式,因為建立二元樹同時資料已經經過初步比較判斷,並依照二元樹建立規則存放資料,其規則如下: (A)第一個輸入資料為此二元樹之樹根 (B)資料以遞迴方式與樹根進行比較,小於樹根置於左子樹,大於樹根置於右子樹。 因為左子樹的內容一定小於樹根,右子樹之值一定大於樹根,因此只要用中序走訪方式就可以得到由小至大排序好的資料。 ->因此如果想求由大到小排列資料,可將最後結果置於堆疊內再POP出來。 考題9: 請說明採用何規則建立二元樹,再採用何種走訪方式可以得到由小到大排序? 範例: 利用中序走訪進行排序 #include usingstd: : endl; usingstd: : cout; usingstd: : cin; #include usingstd: : setw; structtree { intdata; tree*left; tree*right; }; tree*create_tree(tree*,int); voidin(tree*); intmain() { intdata; tree*ptr=NULL; cout<<"Pleaseinputdata,endwith-1: "< cin>>data; while(data! =-1) { ptr=create_tree(ptr,data); cin>>data; } cout<<"\nAftersorting,thedatais"< in(ptr); return0; } tree*create_tree(tree*root,intval) { tree*newnode;//declareanewnode tree*current;//declareacurrentnode tree*backup;//declareabackupnode newnode=newtree;//createaspacetosavedata newnode->data=val; newnode->left=NULL; newnode->right=NULL; if(root==NULL)//Firstpointistheroot { root=newnode; returnroot; } else { for(current=root;current! =NULL;) { backup=current;//reservetherootnode if(current->data>val) current=current->left; else current=current->right; } if(backup->data>val) backup->left=newnode; else backup->right=newnode; } returnroot; } voidin(tree*ptr) { if(ptr! =NULL) { in(ptr->left); cout< in(ptr->right); } } 考題: 請說明如何輸入一組數值資料建立一個二元樹,請將程式碼寫出來? (2)二元搜尋樹(BinarySearchTree) 二分樹: 一個二元樹符合「節點資料大於左子節點樹且小於右子節點樹」稱之。 因為二分樹便於用來搜尋及排序,又稱為二元排序數或二元搜尋樹。 二元搜尋樹之特點: (1)可以是空集合,但若不是空集合則節點上一定要有一個鍵值。 (2)每一個樹根的值須大於左樹根 (3)每一個樹根的值須小於右樹根 (4)左右樹根也是二元搜尋樹 (5)樹的每個節點值不同。 範例: 建立一個二元搜尋樹,並輸入要尋找的值,如果節點中有相等的值,會顯示出搜尋的次數,如果找不到此值,也會顯示訊息。 #include usingstd: : endl; usingstd: : cout; usingstd: : cin; #include usingstd: : setw; structtree { intdata; tree*left; tree*right; }; tree*create_tree(tree*,int); tree*Pre(tree*,int); intmain() { intdata; tree*ptr=NULL; cout<<"Pleaseinputdata,endwith-1: "< cin>>data; while(data! =-1) { ptr=create_tree(ptr,data); cin>>data; } cout<<"\nPleaseinputthesearchingvalue,endwith0"< cin>>data; while(data! =0) { if((Pre(ptr,data))! =NULL)//searchingbinarytree cout<<"Thevalue"< "< else cout<<"Youcannotfindthevalue! "< cout<<"\nPleaseinputthesearchingvalue,endwith0"< cin>>data; } return0; } tree*create_tree(tree*root,intval) { tree*newnode;//declareanewnode tree*current;//declareacurrentnode tree*backup;//declareabackupnode newnode=newtree;//createaspacetosavedata newnode->data=val; newnode->left=NULL; newnode->right=NULL; if(root==NULL)//Firstpointistheroot { root=newnode; returnroot; } else { for(current=root;current! =NULL;) { backup=current;//reservetherootnode if(current->data>val) current=current->left; else current=current->right; } if(backup->data>val) backup->left=newnode; else backup->right=newnode; } returnroot; } tree*Pre(tree*ptr,intval) { inti=1; while(ptr! =NULL) { if(ptr->data==val) { cout<<"Finally,thesearchingtimesare"< "< returnptr; } elseif(ptr->data>val) ptr=ptr->left; else ptr=ptr->right; i++; } returnNULL; } 考題10: 請寫出二元搜尋tree,搜尋部份之函數,並加以文字說明。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第五章 树状结构 第五 树状 结构
![提示](https://static.bdocx.com/images/bang_tan.gif)