下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
數(shù)據(jù)結(jié)構(gòu)與算法
—樹主講教員:段凌宇2014年5月07日
北京大學(xué)信息科學(xué)與技術(shù)學(xué)院,轉(zhuǎn)載或翻印必究大綱5.1樹的概念5.2樹的鏈?zhǔn)酱鎯?chǔ)5.3樹的順序存儲(chǔ)5.4K叉樹北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page2北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page35.1樹的概念5.1.1樹和森林5.1.2 森林與二叉樹的等價(jià)轉(zhuǎn)換5.1.3樹的抽象數(shù)據(jù)類型5.1.4樹的周游北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page4樹的邏輯結(jié)構(gòu)包含n個(gè)結(jié)點(diǎn)的有窮集合K(n>0),且在K上定義了一個(gè)關(guān)系N,關(guān)系N滿足以下條件:
有且僅有一個(gè)結(jié)點(diǎn)k0∈K,它對(duì)于關(guān)系N來說沒有前驅(qū),
結(jié)點(diǎn)k0稱作樹的根;除結(jié)點(diǎn)k0外,K中每個(gè)結(jié)點(diǎn)對(duì)于關(guān)系N都有且僅有一個(gè)前驅(qū);除結(jié)點(diǎn)k0外的任何結(jié)點(diǎn)k∈K,都存在一個(gè)結(jié)點(diǎn)序列k0,k1,…,ks,使得k0就是樹根,且ks=k,
其中有序?qū)?lt;ki-1,ki>∈N(1≤i≤s)。
這樣的結(jié)點(diǎn)序列稱為從根到結(jié)點(diǎn)k的一條路徑。北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page5樹的遞歸定義樹是包括n個(gè)結(jié)點(diǎn)的有限集合T(n≥1),使得:有一個(gè)特別標(biāo)出的稱作根的結(jié)點(diǎn)除根以外的其它結(jié)點(diǎn)被分成m個(gè)(m≥0)不相交的集合T1,T2,…,Tm,而且這些集合的每一個(gè)又都是樹;
樹T1,T2,…,Tm稱作這個(gè)根的子樹。只包含一個(gè)結(jié)點(diǎn)的樹必然僅由根組成,包含n>1個(gè)結(jié)點(diǎn)的樹借助于少于n個(gè)結(jié)點(diǎn)的樹來定義。北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page6樹結(jié)構(gòu)中的概念若有序?qū)?lt;
k,k′>
∈N,則稱k是k′的父結(jié)點(diǎn)(或“父母”),而k′則是k的子結(jié)點(diǎn)(或“兒子”、“子女”)若有序?qū)?lt;k,k′>及<k,k″>
∈N,則稱k′和k″互為兄弟若有一條由k到達(dá)ks的路徑,則稱k是ks的祖先,ks
是k的子孫樹形結(jié)構(gòu)中,兩個(gè)結(jié)點(diǎn)的有序?qū)ΓQ作連接這兩結(jié)點(diǎn)的一條邊北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page7沒有子樹的結(jié)點(diǎn)稱作樹葉或終端結(jié)點(diǎn)非終端結(jié)點(diǎn)稱為分支結(jié)點(diǎn)一個(gè)結(jié)點(diǎn)的子樹的個(gè)數(shù)稱為度數(shù)根結(jié)點(diǎn)的層數(shù)為0,其它任何結(jié)點(diǎn)的層數(shù)等于它的父結(jié)點(diǎn)結(jié)點(diǎn)的層數(shù)加1樹T中如果子樹T1,T2,…,Tm的相對(duì)次序是重要的,則稱樹T為有向有序樹,簡稱有序樹??梢苑QT1是根的第一棵子樹,T2是根的第二棵子樹,等等。北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page8森林與樹森林(forest):零棵或多棵不相交的樹的集合。(通常是有序集合)自然界的樹和森林是不同的概念,而數(shù)據(jù)結(jié)構(gòu)的樹和森林只有微小的差別。刪去樹根,樹就變成森林;加上一個(gè)結(jié)點(diǎn)作樹根,森林就變成樹。北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page95.1樹的概念5.1.1樹和森林5.1.2 森林與二叉樹的等價(jià)轉(zhuǎn)換5.1.3樹的抽象數(shù)據(jù)類型5.1.4樹的周游北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page10森林與二叉樹的等價(jià)轉(zhuǎn)換×××北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page11森林與二叉樹的等價(jià)轉(zhuǎn)換樹或森林與二叉樹之間存在一個(gè)自然的一一對(duì)應(yīng)的關(guān)系任何森林都唯一地對(duì)應(yīng)到一棵二叉樹;反過來,任何二叉樹也都唯一地對(duì)應(yīng)到一個(gè)森林。樹所對(duì)應(yīng)的二叉樹里結(jié)點(diǎn)n的左子結(jié)點(diǎn)是結(jié)點(diǎn)n在原來樹里的第一個(gè)子結(jié)點(diǎn)結(jié)點(diǎn)n的右子結(jié)點(diǎn)是結(jié)點(diǎn)n在原來樹里的下一個(gè)兄弟北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page12森林到二叉樹等價(jià)轉(zhuǎn)換
的精確定義森林F看作樹的有序集合,F(xiàn)=(T1,T2,…,Tn),對(duì)應(yīng)于F的二叉樹B(F)的定義是:若n=0,則B(F)為空若n>0,則B(F)的根是T1的根W1,B(F)的左子樹是B(T11,T12,…,T1m),其中T11,T12,…,T1m是W1的子樹;B(F)的右子樹是B(T2,…,Tn)。北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page13二叉樹到森林的等價(jià)轉(zhuǎn)換設(shè)B是一棵二叉樹,r是B的根,L是r的左子樹,
R是r的右子樹,則對(duì)應(yīng)于B的森林F(B)的定義:若B為空,則F(B)是空的森林;若B不為空,則F(B)是一棵樹T1
+森林F(R),其中樹T1的根為r,r的子樹為F(L)。北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page145.1樹的概念5.1.1樹和森林5.1.2 森林與二叉樹的等價(jià)轉(zhuǎn)換5.1.3樹的抽象數(shù)據(jù)類型5.1.4樹的周游北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page15樹/森林的
結(jié)點(diǎn)抽象數(shù)據(jù)類型 template<classT> classTreeNode {
public: TreeNode(constT&);//拷貝構(gòu)造函數(shù)
virtual~TreeNode(){};//析構(gòu)函數(shù)
boolisLeaf(); //如果結(jié)點(diǎn)是葉,返回true TValue(); //返回結(jié)點(diǎn)的值
TreeNode<T>*LeftMostChild();//返回第一個(gè)左孩子
TreeNode<T>*RightSibling();//返回右兄弟北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page16
//設(shè)置結(jié)點(diǎn)的值
voidsetValue(T&);
//設(shè)置左子結(jié)點(diǎn)
voidsetChild(TreeNode<T>*pointer);
//設(shè)置右兄弟
voidsetSibling(TreeNode<T>*pointer);
//以第一個(gè)左子結(jié)點(diǎn)身份插入結(jié)點(diǎn)
voidInsertFirst(TreeNode<T>*node);
//以右兄弟的身份插入結(jié)點(diǎn)
voidInsertNext(TreeNode<T>*node);};北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page17樹/森林的抽象數(shù)據(jù)類型 template<classT> classTree {
public: Tree(); //構(gòu)造函數(shù)
virtual~Tree(); //析構(gòu)函數(shù)
TreeNode<T>*getRoot();
//返回樹中的根結(jié)點(diǎn)
//創(chuàng)建樹中的根結(jié)點(diǎn),使根結(jié)點(diǎn)元素的值為rootValue voidCreateRoot(constT&rootValue);
//判斷是否為空樹,如果是則返回true boolisEmpty();
北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page18//返回current結(jié)點(diǎn)的父結(jié)點(diǎn) TreeNode<T>*Parent(TreeNode<T>*current);
//返回current結(jié)點(diǎn)的前一個(gè)鄰居結(jié)點(diǎn)
TreeNode<T>*PrevSibling(TreeNode<T>*current);
//刪除以subroot為根的子樹的所有結(jié)點(diǎn) voidDeleteSubTree(TreeNode<T>*subroot);
//先根深度優(yōu)先周游樹 voidRootFirstTraverse(TreeNode<T>*root);
//后根深度優(yōu)先周游樹 voidRootLastTraverse(TreeNode<T>*root); //寬度優(yōu)先周游樹
voidWidthTraverse(TreeNode<T>*root);};北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page195.1樹的概念5.1.1樹和森林5.1.2 森林與二叉樹的等價(jià)轉(zhuǎn)換5.1.3樹的抽象數(shù)據(jù)類型5.1.4樹的周游北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page20森林的深度優(yōu)先周游
先根次序
a)訪問頭一棵樹的根
b)在先根次序下周游頭一棵樹樹根的所有子樹
c)在先根次序下依次周游其他的樹
后根次序
a)在后根次序下周游頭一棵樹樹根的所有子樹
b)訪問頭一棵樹的根
c)在后根次序下依次周游其他的樹北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page21森林的周游
示例ABCKDEFGHJ先根次序周游:A
B
C
K
D
E
H
F
J
G后根次序周游:BKCAHEJFGD廣度優(yōu)先周游:ADBCEFGKHJ北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page22先根深度優(yōu)先
周游樹程序?qū)崿F(xiàn)template<classT>voidTree<T>::RootFirstTraverse(TreeNode<T>*root){if(root!=NULL){Visit(root->Value());//訪問當(dāng)前結(jié)點(diǎn)root=root->LeftMostChild(); while(root!=NULL){
RootFirstTraverse(root); root=root->RightSibling();//周游其他的子樹
}}}北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page23后根深度優(yōu)先
周游樹程序?qū)崿F(xiàn)template<classT>voidTree<T>::RootLastTraverse(TreeNode<T>*root){TreeNode<T>*pointer=root;if(root!=NULL){pointer=root->LeftMostChild(); while(pointer!=NULL){
RootLastTraverse(pointer); pointer=pointer->RightSibling();//周游其他的子樹
}Visit(root->Value());//訪問當(dāng)前結(jié)點(diǎn)}}北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page24寬度優(yōu)先
周游樹的程序?qū)崿F(xiàn)template<classT>voidTree<T>::WidthTraverse(TreeNode<T>*root){ usingstd::queue; //使用STL隊(duì)列
queue<TreeNode<T>*>aQueue; TreeNode<T>*pointer=root; if(pointer)
aQueue.push(pointer); while(!aQueue.empty()){pointer=aQueue.front();//取隊(duì)列首結(jié)點(diǎn)指針Visit(pointer->Value());//訪問當(dāng)前結(jié)點(diǎn)北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page25
pointer=pointer->LeftMostChild();
while(pointer){aQueue.push(pointer);pointer=pointer->RightSibling();};aQueue.pop(); //出隊(duì)列}}北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page26深度優(yōu)先周游森林
versus
深度優(yōu)先周游等價(jià)的二叉樹按先根次序周游森林等同按前序法周游對(duì)應(yīng)的二叉樹按后根次序周游森林等同按中序法周游對(duì)應(yīng)的二叉樹北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page27先根深度優(yōu)先
周游森林程序?qū)崿F(xiàn)template<classT>voidTree<T>::RootFirstTraverse(TreeNode<T>*root){while(root!=NULL){Visit(root->Value());//訪問當(dāng)前結(jié)點(diǎn)
RootFirstTraverse(root->LeftMostChild()root=root->RightSibling();//周游其他的樹}}template<classT>voidTree<T>::RootLastTraverse(TreeNode<T>*root){ while(root!=NULL){
RootLastTraverse(root->LeftMostChild()); Visit(root->Value());//訪問當(dāng)前結(jié)點(diǎn)
root=root->RightSibling();//周游其他的樹
}}北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page28后根深度優(yōu)先
周游森林程序?qū)崿F(xiàn)大綱5.1樹的概念5.2樹的鏈?zhǔn)酱鎯?chǔ)5.3樹的順序存儲(chǔ)5.4K叉樹北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page29北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page305.2樹的鏈?zhǔn)酱鎯?chǔ)5.2.1子結(jié)點(diǎn)表表示法5.2.2左子結(jié)點(diǎn)/右兄弟結(jié)點(diǎn)表示法5.2.3動(dòng)態(tài)結(jié)點(diǎn)表示法5.2.4動(dòng)態(tài)“左子結(jié)點(diǎn)/右兄弟結(jié)點(diǎn)”二叉鏈表表示法5.2.5父指針表示法北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page315.2.1子結(jié)點(diǎn)表表示法“子結(jié)點(diǎn)表”表示法在數(shù)組中存儲(chǔ)樹的結(jié)點(diǎn)。每個(gè)結(jié)點(diǎn)包括結(jié)點(diǎn)值、一個(gè)父指針以及一個(gè)指向子結(jié)點(diǎn)鏈表的指針。每個(gè)分支結(jié)點(diǎn)均存儲(chǔ)其子結(jié)點(diǎn)信息,子結(jié)點(diǎn)按照從左至右的順序形成一個(gè)鏈表(葉子結(jié)點(diǎn)的子結(jié)點(diǎn)鏈表指針為空)。結(jié)點(diǎn)的最左子結(jié)點(diǎn)可由鏈表的第一個(gè)表項(xiàng)直接找到。找到結(jié)點(diǎn)的右側(cè)兄弟結(jié)點(diǎn)要困難一些。北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page325.2.2左子結(jié)點(diǎn)/右兄弟結(jié)點(diǎn)
表示法每個(gè)結(jié)點(diǎn)存儲(chǔ)結(jié)點(diǎn)值,指向父結(jié)點(diǎn)、最左子結(jié)點(diǎn)、右側(cè)兄弟結(jié)點(diǎn)的指針。ADT的基本操作可通過讀取結(jié)點(diǎn)中的一個(gè)值來實(shí)現(xiàn)。如果兩棵樹存儲(chǔ)在同一個(gè)數(shù)組中,那么把其中一個(gè)添加為另一棵樹的子樹只需簡單設(shè)置三個(gè)指針值即可。這種表示法比子結(jié)點(diǎn)表表示法空間效率更高,而且結(jié)點(diǎn)數(shù)組中的每個(gè)結(jié)點(diǎn)僅需要固定大小的存儲(chǔ)空間。北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page335.2.3動(dòng)態(tài)結(jié)點(diǎn)表示法為每個(gè)結(jié)點(diǎn)分配可變的存儲(chǔ)空間。每個(gè)結(jié)點(diǎn)存儲(chǔ)一個(gè)基于數(shù)組的子結(jié)點(diǎn)指針表。子結(jié)點(diǎn)的數(shù)目不變時(shí),這種方法效果最佳;如果子結(jié)點(diǎn)的數(shù)目發(fā)生變動(dòng)(特別是增加),就必須提供一種專門的校正機(jī)制來改變子結(jié)點(diǎn)指針數(shù)組的大小每個(gè)結(jié)點(diǎn)存儲(chǔ)一條子結(jié)點(diǎn)指針鏈表,動(dòng)態(tài)地分配指針空間。本質(zhì)上與“子結(jié)點(diǎn)表”表示法相同(少了指向父結(jié)點(diǎn)的指針,且鏈表中指針不是數(shù)組中的整數(shù)下標(biāo)索引)北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page345.2.4動(dòng)態(tài)“左子結(jié)點(diǎn)/右兄弟結(jié)點(diǎn)”
二叉鏈表表示法本質(zhì)上,我們使用二叉樹來替換樹。左子結(jié)點(diǎn)在樹中是結(jié)點(diǎn)的最左子結(jié)點(diǎn),右子結(jié)點(diǎn)是結(jié)點(diǎn)原來的右側(cè)兄弟結(jié)點(diǎn)。由于樹的每個(gè)結(jié)點(diǎn)均包含固定數(shù)目的指針,而且樹的ADT的每個(gè)函數(shù)均能有效實(shí)現(xiàn),因此動(dòng)態(tài)“左子結(jié)點(diǎn)/右兄弟結(jié)點(diǎn)”表示法比以上介紹的其他方法更為常用。可以很容易地把這種轉(zhuǎn)化推廣到森林,因?yàn)樯种忻靠脴涞母Y(jié)點(diǎn)可以看成互為兄弟結(jié)點(diǎn)。北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page355.2.4動(dòng)態(tài)“左子結(jié)點(diǎn)/右兄弟結(jié)點(diǎn)”
二叉鏈表表示法本質(zhì)上,我們使用二叉樹來替換樹。左子結(jié)點(diǎn)在樹中是結(jié)點(diǎn)的最左子結(jié)點(diǎn),右子結(jié)點(diǎn)是結(jié)點(diǎn)原來的右側(cè)兄弟結(jié)點(diǎn)。由于樹的每個(gè)結(jié)點(diǎn)均包含固定數(shù)目的指針,而且樹的ADT的每個(gè)函數(shù)均能有效實(shí)現(xiàn),因此動(dòng)態(tài)“左子結(jié)點(diǎn)/右兄弟結(jié)點(diǎn)”表示法比以上介紹的其他方法更為常用。可以很容易地把這種轉(zhuǎn)化推廣到森林,因?yàn)樯种忻靠脴涞母Y(jié)點(diǎn)可以看成互為兄弟結(jié)點(diǎn)。北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page36樹結(jié)點(diǎn)抽象數(shù)據(jù)類型
的程序?qū)崿F(xiàn)//補(bǔ)充與具體實(shí)現(xiàn)相關(guān)的私有成員變量申明…private: Tm_Value; //樹結(jié)點(diǎn)的值
TreeNode<T>* pChild; //第一個(gè)左子結(jié)點(diǎn)
TreeNode<T>* pSibling; //右兄弟結(jié)點(diǎn)北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page37樹結(jié)點(diǎn)抽象數(shù)據(jù)類型
的程序?qū)崿F(xiàn)
//公有成員函數(shù)的具體實(shí)現(xiàn)
template<classT>
TreeNode<T>::TreeNode(constT&value)
{
m_Value=value; pChild=NULL; pSibling=NULL; }
template<classT>
TTreeNode<T>::Value()
{
returnm_Value;
}
template<classT>
boolTreeNode<T>::isLeaf()
{
if(pChild==NULL)
returntrue;
returnfalse;
}北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page38template<classT>void
TreeNode<T>::setValue(T&value) {
m_Value=value;
//設(shè)置結(jié)點(diǎn)的值}template<classT>TreeNode<T>*
TreeNode<T>::LeftMostChild(){
returnpChild;
//返回第一個(gè)左子結(jié)點(diǎn)}template<classT>TreeNode<T>*
TreeNode<T>::RightSibling(){
returnpSibling;
//返回右兄弟}北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page39template<classT>voidTreeNode<T>::setChild(TreeNode<T>*pointer){
pChild=pointer;
//設(shè)置左子結(jié)點(diǎn)}template<classT>voidTreeNode<T>::setSibling(TreeNode<T>*pointer){
pSibling=pointer;
//設(shè)置右兄弟}北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page40template<classT>voidTreeNode<T>::InsertFirst(TreeNode<T>*node){
if
(!pChild)
pChild=node;
//若當(dāng)前結(jié)點(diǎn)原先無子女 else
{
//若當(dāng)前結(jié)點(diǎn)原先已有子女
node->pSibling=pChild;
pChild=node; }}以當(dāng)前結(jié)點(diǎn)TreeNode第一個(gè)子結(jié)點(diǎn)的身份插入結(jié)點(diǎn)北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page41以當(dāng)前結(jié)點(diǎn)TreeNode右兄弟的身份插入結(jié)點(diǎn)template<classT>voidTreeNode<T>::InsertNext(TreeNode<T>*node){
if(!pSibling) pSibling=node;//若當(dāng)前結(jié)點(diǎn)原先無右兄弟 else{
//若當(dāng)前結(jié)點(diǎn)原先已有右兄弟
node->pSibling=pSibling; pSibling=node; }}北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page42樹抽象數(shù)據(jù)類型的
程序?qū)崿F(xiàn)private: TreeNode<T>*root;
//樹根結(jié)點(diǎn)
//返回current的父結(jié)點(diǎn),由函數(shù)Parent調(diào)用
TreeNode<T>*getParent(TreeNode<T>*root,
TreeNode<T>*current);
//刪除以root為根的子樹的所有結(jié)點(diǎn)
voidDeleteNodes(TreeNode<T>*root); 北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page43template<classT>Tree<T>::Tree() {
root=NULL;}template<classT>Tree<T>::~Tree()
{
while(root)
DeleteSubTree(root);}template<classT>TreeNode<T>*Tree<T>::getRoot()
{
returnroot;}北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page44template<classT>voidTree<T>::CreateRoot(constT&rootValue){//創(chuàng)建樹中的根結(jié)點(diǎn),使根結(jié)點(diǎn)元素的值為rootValue
if(!root)
root=newTreeNode<T>(rootValue);}template<classT>boolTree<T>::isEmpty(){//判斷是否為空樹,如果是則返回true if(root)
returnfalse; returntrue;}北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page45返回current結(jié)點(diǎn)的
前一個(gè)鄰居結(jié)點(diǎn)的程序?qū)崿F(xiàn)template<classT>TreeNode<T>*
Tree<T>::PrevSibling
(TreeNode<T>*current){
usingstd::queue;
//使用STL隊(duì)列
queue<
TreeNode<T>*
>aQueue;
//標(biāo)識(shí)當(dāng)前結(jié)點(diǎn) TreeNode<T>*pointer=root;
//標(biāo)識(shí)當(dāng)前結(jié)點(diǎn)的前一個(gè)兄弟結(jié)點(diǎn)
TreeNode<T>*prev=NULL;
北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page46if
((current==NULL)||(pointer==NULL)
||(current==pointer))
//當(dāng)前結(jié)點(diǎn)為空、樹為空、當(dāng)前結(jié)點(diǎn)為根結(jié)點(diǎn) returnNULL; while(pointer){//找到當(dāng)前結(jié)點(diǎn) if(pointer==current) returnprev;
aQueue.push(pointer); prev=pointer;//沿當(dāng)前結(jié)點(diǎn)右兄弟結(jié)點(diǎn)鏈尋找 pointer=pointer->pSibling;}//以廣度優(yōu)先周游方式尋找前一鄰結(jié)點(diǎn)
while(!aQueue.empty()){ prev=NULL; pointer=aQueue.front(); //出隊(duì)列 aQueue.pop();
//下降到左子結(jié)點(diǎn)
pointer=pointer->LeftMostChild();
北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page47北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page48while(pointer){ if(pointer==current)returnprev; aQueue.push(pointer); prev=pointer; pointer=pointer->pSibling;
} } returnNULL;}北京大學(xué)信息學(xué)院,轉(zhuǎn)載或翻印必究Page49
template<classT> voidTree<T>::DeleteNodes(TreeNode<T>*root) {
if(root){
//遞歸刪除第一子樹
DeleteNodes(root->LeftMostChild());
//遞歸刪除其他子樹
DeleteNodes(root->RightSibling()); //刪除根結(jié)點(diǎn)
deleteroot;
} }刪除以root為根的子樹的所有結(jié)點(diǎn)
template<classT> voidTree<T>::
DeleteSubTree(TreeNode<T>*subroot) {
TreeNode<T>*pointer=PrevSibling(subroot); if(pointer==NULL) {//subroot為最左子結(jié)點(diǎn)的情況
pointer=Parent(subroot); if(pointer){ pointer->pChild=subroo
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年堿式硫酸鉻項(xiàng)目成效分析報(bào)告
- 2024至2030年中國車載型農(nóng)藥殘毒速測(cè)設(shè)備數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 2024至2030年中國皮鞋美容機(jī)數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 2024至2030年中國電腦開料硬質(zhì)合金鋸片數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 2024至2030年中國臥式鏜銑加工中心數(shù)據(jù)監(jiān)測(cè)研究報(bào)告
- 2024至2030年攀登作業(yè)包項(xiàng)目投資價(jià)值分析報(bào)告
- 2024年中國觸摸延時(shí)開關(guān)市場(chǎng)調(diào)查研究報(bào)告
- 2024年壓線帽自動(dòng)裝配機(jī)項(xiàng)目可行性研究報(bào)告
- 2024年人參提取物項(xiàng)目可行性研究報(bào)告
- 企業(yè)間借款合同條款解讀
- 長沙民政職業(yè)技術(shù)學(xué)院單招《職業(yè)技能測(cè)試》參考試題庫(含答案)
- 藥物健康宣教
- 網(wǎng)絡(luò)工程職業(yè)生涯展示
- 哈利波特與混血王子
- 《汽車鈑金噴涂技術(shù)》 課件 任務(wù)11.2車身鋼制外板外形修復(fù)機(jī)修復(fù)
- 不銹鋼電鍍工藝流程
- IgG4相關(guān)疾病的護(hù)理查房
- 如何做好醫(yī)院學(xué)科建設(shè)
- 干部職工禁毒培訓(xùn)課件
- 景區(qū)服務(wù)提升培訓(xùn)課件
- 補(bǔ)鉀原則和注意事項(xiàng)
評(píng)論
0/150
提交評(píng)論