版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
9二叉樹按二叉鏈表形式存儲,對于樹中每個元素值為x的結(jié)點,刪去以它為根的子樹,并釋放相應(yīng)的
空間。
刪除以元素值X為根的子樹,只要能刪除其左、右子樹,就可以釋放值為X的根結(jié)點,因此宜采用后序遍
歷。
算法思想:刪除值為X的結(jié)點,意味著應(yīng)將其父結(jié)點的左(右)子女指針置空,用層次遍歷易于找到某
結(jié)點的父結(jié)點。
本題要求刪除樹中每個元素值為X的結(jié)點的子樹,因此要遍歷完整棵二叉樹。
voidDeleteXTree(BiTreebt)〃刪除以bt為根的子樹
(
if(bt){
DeleteTree(bt->lchild);
DeleteTree(bt->rchild);〃刪除bt的左子樹、右子樹
free(bt);〃釋放被刪結(jié)點所占的存儲空間
)
)
〃在二叉樹上查找所有以x為元素值的結(jié)點,并刪除以其為根的子樹
voidSearch(BiTreebt,intx)
(
BiTreeQ口;〃Q是存放二叉樹結(jié)點指針的隊列,容量足夠大
if(bt){
if(bt->data==x){〃若根結(jié)點值為x,則刪除整棵樹
DeleteXTree(p->lchild);
exit(O);
)
InitQueue(Q);
EnQueue(Q,bt);
while(!lsEmpty(Q)){
DeQueue(Q,p);
if(p->lchild)〃若左子女非空
if(p->lchild->data==x){〃左子樹符合則刪除左子樹
DeleteXTree(p->lchild);p->lchild=NULL;〃父結(jié)點的左子女置空
}
else
EnQueue(Q,p->lchild);〃左子樹入隊列
if(p->rchild)〃若右子女非空
if(p->rchiid->data==x){〃右子女符合則刪除右子樹
DeleteXTree(p->rchild);p->rchild=NULL;〃父結(jié)點的右子女置空
)
else
EnQueue(Q,p->rchild);〃右子女入隊列
)
}
第1頁共n頁
10二叉樹中查找值為x的結(jié)點,打印值為x的結(jié)點的所有祖先,假設(shè)值為x的結(jié)點不多于一個。
/*
算法思想:采用非遞歸后序遍歷,最后訪問根結(jié)點,訪問到值為X的結(jié)點時,棧中所有元素均為該結(jié)點
的祖先,依次出棧打印即可。因為查找的過程就是后序遍歷的過程,因此使用的棧的深度不超過樹的深
度。
7
typedefstruct{
BiTreet;
inttag;//tag=0表示左子女已被訪問,tag=l表示右子女已被訪問
}stack;
voidSearch(BiTreebtjntx)
(
stacks口;〃棧容量足夠大
top=0;
while(bt!=NULL||top>0)
{
while(bt!=NULL&&bt->data!=x)〃結(jié)點入棧
(
s[++top].t=bt;
s[top].tag=0;
bt=bt->lchild;〃沿左分支向下
}
if(bt->data==x)
(
printf("所查結(jié)點的所有祖先結(jié)點的值為:\n");〃找到x
for(i=l;i<=top;i++)
printf(”%d,s[i].t?>data);〃輸出祖先值后結(jié)束
exit(l);
)
while(top!=0&&s[top].tag==l)
top-;〃退棧(空遍歷)
if(top!=0)
(
s[top].tag=1;
bt=s[top].t->rchild;〃沿右分支向下遍歷
}
}//while
第2頁共11頁
11二叉樹中p和q分別為指向該二叉樹中任意兩個結(jié)點的指針,試編寫算法找到p和q的最近公共
祖先結(jié)點ro
后序遍歷最后訪問根結(jié)點,即在遞歸算法中,根是壓在棧底的。
本題要找P和q的最近公共祖先結(jié)點r,不失一般性,設(shè)p在q的左邊。
算法思想:采用后序非遞歸算法,棧中存放二又樹結(jié)點的指針,當訪問到某結(jié)點時,棧中所有元素均為
該結(jié)點的祖先。后序遍歷必然先遍歷到結(jié)點P,棧中元素均為p的祖先。先將棧復(fù)制到另一輔助棧中。繼
續(xù)遍歷到結(jié)點q時,將棧中元素從棧頂開始逐個到輔助棧中去匹配,第一個匹配(即相等)的元素就是
結(jié)點P和q的最近公共祖先。
typedefstruct{
BiTreet;
inttag;//tag=O表示左子女已被訪問,tag=l表示右子女已被訪問
}stack;
stacks[Lsl[];〃棧,容量足夠大
BiTreeAncester(BiTreeROOTBiTNode*p,BiTNode*q){
top=0;
bt=ROOT;
while(bt!=NULL&&bt!=p&&bt!=q){〃結(jié)點入棧
while(bt!=NULL){
S[++top].t=bt;
s[topj.tag=0;
bt=bt->lchild;
"/沿左分支向下
while(top!=0&&s[top].tag==1){
〃假定p在q的左側(cè),遇到p時,棧中元素均為p的祖先
if(s[top].t==p){
for(i=l;i<=top;i++){
sl[i]=s[i];
topi=top;
}〃將棧s的元素轉(zhuǎn)入輔助棧si保存
if(s[top].t==q)〃找到q結(jié)點
for(i=top;i>0;i-){〃將棧中元素的樹結(jié)點到si中去匹配
for(j=topl;j>0;j-)
if(sl[j].t==s[i].t)
returns[i].t;//p和q的最近公共祖先已找到
)
top-;〃退棧
}//while
if(top!=0){
s[top].tag=1;
bt=s[top].t->rchild;
)〃沿右分支向下遍歷
}//while
returnNULL;//p和q無公共祖先
第3頁共11頁
12二叉樹按二叉鏈表形式存儲,試求非空二叉樹b的寬度(即具有結(jié)點數(shù)最多的那一層的結(jié)點個數(shù))。
采用層次遍歷的方法求出所有結(jié)點的層次,并將所有結(jié)點和對應(yīng)的層次放在一個隊列中。然后通過掃描
隊列求出各層的結(jié)點總數(shù),最大的層結(jié)點總數(shù)即為二又樹的寬度。
注意:本題隊列中的結(jié)點,在出隊后仍需要保留在隊列中,以便求二又樹的寬度,所以設(shè)置的隊列采用非
環(huán)形隊列,否則在出隊后可能被其他結(jié)點覆蓋,無法再求二又樹的寬度。
typedefstruct(
BiTreedata[MaxSize];//i保存隊列中的結(jié)點指針
intlevel[MaxSize];〃保存data中相同下標結(jié)點的層次
intfront,rear;
}Qu;
intBTWidth(BiTreeb){
BiTreep;
intk,max,i,n;
Qu.front二Qu.rear=-1;〃隊列為空
Qu.rear++;
Qu.data[Qu.rear]二b;〃根結(jié)點指針入隊
Qu.level[Qu.rear]=l;〃根結(jié)點層次為1
while(Qu.front<Qu.rear){
Qu.front++;p=Qu.data[Qu.front];k=Qu.level[Qu.front];
if(p->lchild!=NULL){〃左孩子進隊列
Qu.rear++;Qu.data[Qu.rear]=p->lchild;Qu.level[Qu.rear]=k+l;
)
if(p->rchild1=NULL){〃右孩子進隊列
Qu.rear++;Qu.data[Qu.rear]=p->rchild;Qu.level[Qu.rear]=k+l;
)
}//while
max=0;i=0;//max保存同一層最多的結(jié)點個數(shù)
k=1;//k表示從第一層開始查找
while(i<=Qu.rear){〃i掃描隊中所有元素
n=0;〃n統(tǒng)計第k層的結(jié)點個數(shù)
while(i<=Qu.rear&6Qu.level[i]==k){
n++;i++;
)
k=Qu.level[i];
if(n>max)max=n;〃保存最大的n
)
returnmax;
第4頁共U頁
17二叉樹按二叉鏈表形式存儲,設(shè)計求二叉樹T的WPL的算法
/*
考查二叉樹的帶權(quán)路徑長度,二叉樹的帶權(quán)路徑長度為每個葉結(jié)點的深度與權(quán)值之積的總和,可以使用
先序遍歷解決問題。
1)算法的基本設(shè)計思想。
基于先序遞歸遍歷的算法思想是用一個static變量記錄wpl,把每個結(jié)點的深度作為遞歸函數(shù)的一個參數(shù)
傳遞。
算法步驟如下:
①若該結(jié)點是葉結(jié)點,則變量wpl加上該結(jié)點的深度與權(quán)值之積。
②若該結(jié)點是非葉結(jié)點,則左子樹不為空時,對左子樹調(diào)用遞歸算法,右子樹不為空,對右子樹調(diào)用遞
歸算法,深度參數(shù)均為本結(jié)點的深度參數(shù)加1。
③最后返回計算出的wpl即可。
PS:當static關(guān)鍵字用于代碼塊內(nèi)部的變量的聲明時;用于修改變量的存儲類型,即從自動變量修改為靜態(tài)
變量,但變量的鏈接屬性和作用域不受影響。用這種方式聲明的變量在程序執(zhí)行之前創(chuàng)建,并在程序的
整個執(zhí)行期間一直存在,而不是每次在代碼塊開始執(zhí)行時創(chuàng)建,在代碼塊執(zhí)行完畢后銷毀。也就是說,
它保持局部變量內(nèi)容的持久。靜態(tài)局部變量的生存期雖然為整個源程序,但其作用域仍與局部變量相同,
即只能在定義該變量的函數(shù)內(nèi)使用該變量。退出該函數(shù)后,盡管該變量還繼續(xù)存在,但不能使用它。
*/
//二叉樹結(jié)點的數(shù)據(jù)類型定義如下:
typedefstructBiTNode{
intweight;
structBiTNode*lchild,*rchild;
JBiTNode,*BiTree;
intWPL(BiTreeroot){
returnwpl_PreOrder(root,0);
intwpl_Preorder(BiTreeroot,intdeep){
staticintwpl=0;〃定義一個static變量存儲wpl
if(root->lchild==NULL&&root->rchild==NULL)〃若為葉結(jié)點,累積wpl
wpl+=deep*root->weight;
if(root->lchild!=NULL)〃若左子樹不空,對左子樹遞歸遍歷
wpl_PreOrder(root->lchild,deep+l);
if(root->rchild!=NULL)〃若右子樹不空,對右子樹遞歸遍歷
wpl_PreOrder(root->rchild,deep+l);
returnwpl;
第5頁共U頁
18將給定的表達式(二叉樹)轉(zhuǎn)換為等價的中綴表達式(通過括號反映操作符的計算次序)并輸出。
/*
1)算法的基本設(shè)計思想:
表達式樹的中序序列加上必要的括號即為等價的中綴表達式??梢曰诙鏄涞闹行虮闅v策略得到所需
的表達式。
表達式樹中分支結(jié)點所對應(yīng)的子表達式的計算次序,由該分支結(jié)點所處的位置決定。為得到正確的中綴
表達式,需要在生成遍歷序列的同時,在適當位置增加必要的括號。顯然,表達式的最外層(對應(yīng)根結(jié)
點)和操作數(shù)(對應(yīng)葉結(jié)點)不需要添加括號。
2)算法實現(xiàn):
將二又樹的中序遍歷遞歸算法稍加改造即可得本題的答案。除根結(jié)點和葉結(jié)點外,遍歷到其他結(jié)點時在
遍歷其左子樹之前加上左括號,遍歷完右子樹后加上右括號。
*/
voidBtreeToE(BTree*root){
BtreeToExp(root,1);〃根的高度為1
voidBtreeToExp(BTree*root,intdeep)
(
if(root==NULL)return;〃空結(jié)點返回
elseiffroot->left==NULL&&root->right==NULL)〃若為葉結(jié)點
printf("%s",root->data);
else(
if(deep>l)printf("(");〃輸出操作數(shù),不加括號
BtreeToExp(root->left,deep+l);〃若有子表達式貝(I力口1層括號
printf("%s",root->data);〃輸出操作符
BtreeToExp(root->right,deep+l);
if(deep>l)printf(")");〃若有子表達式則加1層括號
)
第6頁共n頁
21已知一棵樹的層次序列及每個結(jié)點的度,編寫算法構(gòu)造此時的孩子-兄弟鏈接
/*
本題與樹的層次序列有關(guān)。可設(shè)立一個輔助數(shù)組pointer口存儲新建樹的各結(jié)點的地址,再根據(jù)層次序列與
每個結(jié)點的度,逐個鏈接結(jié)點。
*/
//definemaxNodes15
voidcreatecSTree_Degree(Csfree&T,inte[],intdegree[],intn){
〃根據(jù)樹結(jié)點的層次序列e口和各結(jié)點的度degree口構(gòu)造樹的孩子.兄弟鏈表
〃參數(shù)n是樹結(jié)點個數(shù)
CSNode*pointer=newCSNode[maxNodes];〃判斷pointer[i]為空的語句未寫
inti,j,d,k=0;
for(i=0;i<n;i++){〃初始化
pointer[i]=newcsNode;〃判斷pointer]]為空的語句未寫
pointer[i]->data=e[i];
pointer[i]->lchild=pointer[i]->rsibling=NULL;
}
for(i=0;i<n;i++){
d二degree]];〃結(jié)點i的度數(shù)
if(d){
1<++;〃1<為子女結(jié)點序號
pointe巾卜>lchild=pointer伙];〃建立i與子女k間的鏈接
for(j=2;j<=d;j++){
k++;
pointer[k-l]->rsibling=pointer[k];
)
)
T=pointer[0];
delete[]pointer;
第7頁共11頁
24利用二叉樹遍歷的思想編寫一個判斷二叉樹是否平衡二叉樹的算法
/*
設(shè)置二叉樹的平衡標記balance,標記返回二又樹bt是否為平衡二叉樹,若為平衡二叉樹,
則返回1,否則返回0:h為二又樹bt的高度。采用后序遍歷的遞歸算法:
1)若bt為空,則高度為0,balance=lo
2)若bt僅有根結(jié)點,則高度為Lbalanced。
3)否則,對bt的左、右子樹執(zhí)行遞歸運算,返回左、右子樹的高度和平衡標記,bt的高度
為最高子樹的高度加1。若左、右子樹的高度差大于1,則balanced;若左、右子樹的
高度差小于等于1,且左、右子樹都平衡時,balance=l,否則balance=0。
*/
voidJudgeAVL(BiTreebt,int&balance,intsh){
〃本算法判斷一個給定的二叉樹是否為平衡二叉樹
intbl=O,br=O,hl=0,hr=O;〃左、右子樹的平衡標記和高度
if(bt==NULL){〃空樹,高度為0
h=0;
balance=l;
elseif(bt->lchild==NULL&6bt->xchild==NULL){〃僅有根結(jié)點,則高度為1
h=l;
balance=l;
)
Judge_AVL(bt->lchild,bl,hl);〃遞歸判斷左子樹
Judge_AVL(bts>rchild,br,hr);〃遞歸判斷右子樹
h=(hl>hr?hl:hr)+1;
if(abs(hl-hr)<2)〃若子樹高度差的絕對值<2,則看左、右子樹是否都平衡
balance=bl&&br;〃66為邏輯與,即左、右子樹都平衡時,二叉樹平衡
else
balance=0;
第8頁共U頁
4分別采用基于深度優(yōu)先遍歷和廣度優(yōu)先遍歷算法判別以鄰接表方式存儲的有向圖中是否存在由頂點vi
到頂點vj的路徑(用)o注意,算法中涉及的圖的基本操作必須在此存儲結(jié)構(gòu)上實現(xiàn)。
/*
兩個不同的遍歷算法都采用從頂點V,出發(fā),依次遍歷圖中每個頂點,直到搜索到頂點vj,若能夠搜索到
vj,則說明存在由頂點vi到頂點j的路徑。
〃深度優(yōu)先遍歷算法的實現(xiàn)如下
intvisited[MAXSIZE]={0};〃訪問標記數(shù)組
intExist_Path_DFS(ALGraphG,inti,intj){
intp;〃頂點序號
if(i==j)
return1;//i就是j
else{
visited[i]=l;〃置訪問標記
for(p=FirstNeighbor(GJ);p>=0;p=NextNeighbor(G,i,p)){
k=p.adjvex;
if(!visited[p]&&Exist_Path_DFS(G,pj))
return1;
}//for
}//else
return0;
〃廣度優(yōu)先遍歷算法的實現(xiàn)如下
intvisited[MAXSI2E]={0};〃訪問標記數(shù)組
intExist_Path_BFS(ALGraphGJntijntj){
〃廣度優(yōu)先判斷有同圖G中頂點vi到頂點vj是否有路徑,是則返回1,否則返回0
InitQueue(Q);
EnQueue(QJ);〃頂點i入隊
while(!isEmpty(Q)){〃非空循環(huán)
DeQueue(Q,u);〃隊頭頂點出隊
visited[u]=l;〃置訪問標記
for(p=FirstNeighbor(G/i);p;p=NextNeighbor(GJ,p)){
〃檢查所有鄰接點
k=p.adjvex;
if(k==j)〃若k==j,則查找成功
return1;
if(!visited[k])〃否則,頂點k入隊
EnQueue(Q,k);
}//for
}//while
return0;
)
第9頁共n頁
312016統(tǒng)考真題】已知由n(n>2)個正整數(shù)構(gòu)成的集合A={akI0<=k<n},將其劃分為兩個不相交的子
集A1和A2,元素個數(shù)分別是nl和n2,Al和4中的元素之和分別為S1和立。設(shè)計一個盡可能高效的
劃分算法,滿足|nl-n2l最小且|S1-S2|最大
/*
1)算法的基本設(shè)計思想
由題意知,將最小的L[n/2]個元素放在A1中,其余的元素放在A2中,分組結(jié)果即可滿足題目要求。仿照
快速排序的思想,基于樞軸將n個整數(shù)劃分為兩個子集。根據(jù)劃分后樞軸所處的位置i
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025版智慧社區(qū)物業(yè)管理委托合同模板3篇
- 2025年度鋼材回收利用合同
- 2025年全球及中國放射性標記服務(wù)行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報告
- 2025-2030全球氮化鎵半導(dǎo)體激光器行業(yè)調(diào)研及趨勢分析報告
- 2025年度個人知識產(chǎn)權(quán)侵權(quán)糾紛調(diào)解協(xié)議3篇
- 2025年度個人房產(chǎn)過戶貸款過橋合同3篇
- 2025版建筑起重機械施工安全協(xié)議書3篇
- 2025年度個人股權(quán)收購與整合服務(wù)合同4篇
- 2025年度個人牧場與乳制品企業(yè)合作合同3篇
- 2025年度鋼管工程建設(shè)項目材料供應(yīng)合同2篇
- 勞務(wù)協(xié)議范本模板
- 2024年全國職業(yè)院校技能大賽高職組(生產(chǎn)事故應(yīng)急救援賽項)考試題庫(含答案)
- 2025大巴車租車合同范文
- 老年上消化道出血急診診療專家共識2024
- 人教版(2024)數(shù)學(xué)七年級上冊期末測試卷(含答案)
- 廣東省廣州黃埔區(qū)2023-2024學(xué)年八年級上學(xué)期期末物理試卷(含答案)
- 2024年國家保密培訓(xùn)
- 2024年公務(wù)員職務(wù)任命書3篇
- 《GMP基礎(chǔ)知識培訓(xùn)》課件
- CFM56-3發(fā)動機構(gòu)造課件
- 會議讀書交流分享匯報課件-《殺死一只知更鳥》
評論
0/150
提交評論