工大數(shù)據(jù)結(jié)構(gòu)第三章作業(yè)_第1頁
工大數(shù)據(jù)結(jié)構(gòu)第三章作業(yè)_第2頁
工大數(shù)據(jù)結(jié)構(gòu)第三章作業(yè)_第3頁
工大數(shù)據(jù)結(jié)構(gòu)第三章作業(yè)_第4頁
工大數(shù)據(jù)結(jié)構(gòu)第三章作業(yè)_第5頁
已閱讀5頁,還剩24頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

數(shù)據(jù)結(jié)構(gòu)與算法上機作業(yè)第三章樹

一、選擇題1、在一棵樹中,如果結(jié)點A有3個兄弟,B是A的雙親,則B的度為D A.1 B.2 C.3 D.42、深度為h的完全二叉樹至少有D個結(jié)點,至多有B個結(jié)點 A.2h B.2h-1 C.2h+1 D.2h-12^(h-1)-1+1=2^(h-1)

前(n-1)層滿,第h層只有一結(jié)點3、具有n個結(jié)點的滿二叉樹有C個葉結(jié)點。 A.n/2 B.(n-1)/2 C.(n+1)/2 D.n/2+1因為二叉樹中,有這樣一個性質(zhì),如果其終端結(jié)點數(shù)(也就是葉子節(jié)點)的個數(shù)為n1,度為2的結(jié)點數(shù)為n2,則n1=n2+1;

假設(shè)葉子節(jié)點有x個,則度為2的個數(shù)為x-1:

所以:2x-1=n;所以x=(n+1)/2(滿二叉樹)

所以葉子節(jié)點個數(shù)為:(n+1)/2

非終端結(jié)點為:(n+1)/2-14、一棵具有25個葉結(jié)點的完全二叉樹最多有B個結(jié)點。 A.48 B.49 C.50 D.515、已知二叉樹的先根遍歷序列是ABCDEF,中根遍歷序列是CBAEDF,則后根遍歷序列是A。 A.CBEFDA B.FEDCBA C.CBEDFA D.不定6、具有10個葉結(jié)點的二叉樹中有B個度為2的結(jié)點。 A.8 B.9 C.10 D.117、一棵非空二叉樹的先序遍歷序列與后序遍歷序列正好相反,則該二叉樹一定滿足C。 A.所有非葉結(jié)點均無左孩子 B.所有非葉結(jié)點均無右孩子 C.只有一個葉子結(jié)點 D.A和B同時成立8、在線索二叉樹中,t所指結(jié)點沒有左子樹的充要條件是B。 A.t->left=NULL B.t->ltag=TRUE C.t->ltag=TRUE且t->left=NULL D.以上都不對9、n個結(jié)點的線索二叉樹上含有的線索數(shù)為C。 A.2n B.n-1 C.n+1 D.nn-1表示結(jié)點的左右子樹,其余n-1指針為空線索取代原來的空鏈10、二叉樹按照某種順序線索化后,任一結(jié)點都有指向其前驅(qū)和后繼的線索,這種說法B。 A.正確 B.錯誤 C.不確定 D.都有可能11、具有n(n>1)個結(jié)點的完全二叉樹中,結(jié)點i(2i>n)的左孩子結(jié)點是D。 A.2i B.2i+1 C.2i-1 D.不存在12、具有64個結(jié)點的完全二叉樹的深度為C。 A.5 B.6 C.7 D.813、將一顆有100個結(jié)點的完全二叉樹從上到下、從左到右一次對結(jié)點進(jìn)行編號,根結(jié)點的五、已知非空二叉樹T,寫一個算法,求度為2的結(jié)點的個數(shù)。要求: 1、定義二叉樹的抽象數(shù)據(jù)類型和型BTREE,并定義基本操作。 2、編寫函數(shù)count2(BTREET),返回度為2的節(jié)點的個數(shù)。 3、在主函數(shù)中,構(gòu)建一個二叉樹,并驗證所編寫的算法。六、用遞歸方法寫一個算法,求二叉樹的葉子結(jié)點數(shù)intleafnum(BTREET)。要求:定義二叉樹的抽象數(shù)據(jù)類型和型BTREE,并定義基本操作。編寫函數(shù)leafnum(BTREET),返回樹T的葉子節(jié)點的個數(shù)。在主函數(shù)中,構(gòu)建一個二叉樹,并驗證所編寫的算法。畫出下圖所表示的二叉樹的中序線索二叉樹和先序線索二叉樹。八、已知二叉樹的先根序列是AEFBGCDHIKJ,中根序列是EFAGBCHKIJD,畫出此二叉樹,并畫出后序線索二叉樹。九、在中序線索二叉樹中插入一個結(jié)點Q作為樹中某個結(jié)點P的左孩子,試給出相應(yīng)的算法。要求:定義中序線索二叉樹的型THTREE以及基本操作。定義函數(shù)voidLInsert(THTREEP,THTREEQ);實現(xiàn)題目要求的操作。在主函數(shù)中,利用操作RInsert和LInsert構(gòu)造一個線索二叉樹,并中序輸出二叉樹的結(jié)點的元素,驗證結(jié)果。#include<iostream>#include<iomanip>#include<cmath>#include<cstdlib>#include<string>usingnamespacestd;typedefintelementtype;structnode{//節(jié)點的型 node*lchild; node*rchild; boolltag; boolrtag; elementtypeelement;};typedefnode*head;//指向樹根roottypedefnode*tree;//指向線索樹的根節(jié)點voidmakeNull(head&h)//將線索二叉樹置空{(diào) h->lchild=h; h->ltag=false; h->rchild=h; h->rtag=true;}headpointTotree(head&h,tree&t)//令head指向tree,注意head指向的并不是根節(jié)點,tree指向根節(jié)點{ h->lchild=t; h->rchild=h; h->ltag=true; h->rtag=true; returnh;}//中根遍歷的下一個節(jié)點node*inNext(node*p){ node*q=p->rchild; if(p->rtag==true)//如果有右子樹,找出右子樹的最左節(jié)點 while(q->ltag==true) q=q->lchild; returnq;}//中根遍歷的上一個節(jié)點node*inPre(node*p){ node*q=p->lchild; if(p->ltag==true)//如果P的左子樹存在,則其前驅(qū)結(jié)點為左子樹的最右結(jié)點 while(q->rtag==true) q=q->rchild; returnq;//左子樹的最右結(jié)點}//中序遍歷voidthInOrder(headh){ node*temp; temp=h; do{ temp=inNext(temp); if(temp!=h) cout<<temp->element<<""; }while(temp!=h);}//插入右孩子voidrInsert(node*s,node*r){ node*w; r->rchild=s->rchild; r->rtag=s->rtag; r->lchild=s; r->ltag=false;//新插入的節(jié)點木有左子樹,所以lchild指向的是父節(jié)點 s->rchild=r; s->rtag=true;//原節(jié)點的右孩子為新插入的節(jié)點 if(r->rtag==true){ //這里是神馬意思呢∑q|?Д?|p,就是如果被插節(jié)點s有右子樹, //找出被插節(jié)點s的的next位置,即右子樹中的最左節(jié)點,令其lchild指向新添加的節(jié)點r //因為插入前該最左節(jié)點的lchild指向的是原來節(jié)點s w=inNext(r); w->lchild=r; }}//插入左孩子voidlInsert(node*s,node*l){ node*w; l->lchild=s->lchild; l->ltag=s->ltag; l->rchild=s; l->rtag=false; s->lchild=l; s->ltag=true; if(l->ltag==true){//與插入右孩子方法相似,只需把左右方向?qū)φ{(diào)即可 w=inPre(l); w->rchild=l; }}intmain(){ headh=newnode; node*root=newnode; node*lc=newnode; node*rc=newnode; node*c=newnode; root->element=1; lc->element=2; rc->element=3; c->element=4; h->rchild=root; h->lchild=h; h->ltag=true; h->rtag=true; root->lchild=h; root->rchild=h; root->ltag=false; root->rtag=false; //構(gòu)造線索樹213 lInsert(root,lc); rInsert(root,rc); thInOrder(h); cout<<endl; //root左邊插入C lInsert(root,c); thInOrder(h); return0;}十、假設(shè)現(xiàn)在有如下的元素:7、16、49、82、5、31、6、2、44。畫出將每一個元素插入堆中以后的最大堆。要求:利用基本操作Insert的基本原理,先用第一個元素7構(gòu)成一個二叉樹,然后將第二個元素16插入該二叉樹中,再將第三個元素49插入堆中,……,直到最后一個元素插入為止。上述過程要求畫圖完成。十一、編寫一個函數(shù),在最大堆中查找任意元素,并分析其時間復(fù)雜度。要求:定義最大堆的型HEAP及其基本操作。定義函數(shù)intFind(HEAPH,Elementtypee),查找e是否為堆的元素,如果是,返回該元素在堆中的位置,如果不是,返回0。(提示:利用最大堆的元素特點進(jìn)行查找,可降低復(fù)雜度)在主函數(shù)中首先構(gòu)建一個二叉樹,然后驗證所構(gòu)造的函數(shù)。typedefstryct{intkey;datathpedata;}elementtype;Typedefstruct{Elementtypeelements[Maxsize];intn;}HEAP;VoidMaxHeap(HEAPheap)//創(chuàng)建一個空堆{heap.n=0;}BoolHeapEmpty(HEAPheap)//判斷堆是否為空{(diào)If(!(heap.n))returntrue;Elsereturnfalse;}BoolHeapFull(HEAPheap)//判斷堆是否為滿{if(heap.n==Maxsize-1)returntrue;Elsereturnfalse;}VoidInsert(HEAP&heap,elementtypeelement)//在堆heap中插入元素為element的結(jié)點{IntI;If(!HeapFull(heap)){I=heap.n+1;While((i!=1)&&(element.data>heap.elements[i/2].data)){heap.elements[i]=heap.elements[i/2];i/=2;}Heap.n++;Heap.elements[i]=element;}}ElementtypeDeleteMax(HEAP&heap)//刪除堆中最大元素{intparaent=1,child=2;Elementtypeelement,tmp;If(!HeapEmpty(heap)){Element=heap.elements[1];Tmp=heap.elements[heap.n-];While(child<=heap.n){If((child<heap.n)&&(heap.elements[child].data<heap.elements[child+1].data))child++;If(tmp.data>=heap.elements[child].data)break;Heap.elements[paraent]=heap.elements[child];Paraent=child;Child*=2;}Heap.elements[paraent]=tmp;Returnelement;}}IntFind(HEAP,datatypex){intm=1;While((m<H.n)&&(H.elements[m].data!=x)){If(H.elements[m].data<x)If(H.elements[m+1].data>=x)m++;elsereturn0;elsem++;}if(m<=H.n)returnm;elsereturn0;}Intmain(){HEAPH;Elementtypeelement;Intdata[]={1,3,5,7,9,11,13};H.n=0;For(inti=0;i<7;i++){element.key=i+1;Element.data=data[i];Insert(H,element);}for(inti;i<=H.n;i++)cout<<H.elements[i].data<<endl;DeleteMax(H);For(inti=1;i<=H.n;i++)cout<<H.elements[i].data<<’’;Cout<,endl;Cout<<”查找的元素:”;Intx;Cin>>x;Cout<<Find(H,x)<<endl;}十二、給定葉子結(jié)點的權(quán)值集合{15,3,14,2,6,9,16,17},構(gòu)造相應(yīng)的哈夫曼樹,并計算其帶權(quán)路徑長度。十三、已知n=9和一組等價關(guān)系:1≡5、6≡8、7≡2、9≡8、3≡7、4≡2、9≡3 試應(yīng)用抽象數(shù)據(jù)類型MFSET設(shè)計一個算法,按輸入的等價關(guān)系進(jìn)行等價分類。#include<iostream.h>

#define

n

9//MEFSET元素個數(shù)

//MFSET抽象數(shù)據(jù)型struct

mfnode{

int

father;//指向父節(jié)點的鏈

int

count;//樹結(jié)點個數(shù)

};

typedef

mfnode

MFSET[n+1];

void

Union(int

A,

int

B,

MFSET

C)//合并A和B

{

if(C[A].count>C[B].count)

{

C[B].father=A;//B并入A

C[A].count+=C[B].count;

}

else

{

C[A].father=B;//A并入B

C[B].count+=C[A].count;

}

}

int

Find(int

x,

MFSET

C)//求包含元素x的樹的根

{

int

f;

f=x;

while(C[f].father!=0)//未到根

f=C[f].father;

return

f;

}

void

Initial(int

A,

MFSET

C)//集合A只包含元素A

{

C[A].father=0;

C[A].count=1;

}

//

等價分類

void

Equivalence(MFSET

S)

{

int

i,

j,

m,

k;

for(i=1;

i<=n;

i++)

Initial(i,

S);

cin>>i;

cin>>j;

while(!(i==0

&&

j==0))//輸入0,0結(jié)束等價分類

{

k=Find(i,

S);

m=Find(j,

S);

if(k!=m)

Union(k,

m,

S);

cin>>i;

cin>>j;

}

}

void

print_MFSET(MFSET

S)//輸出等價類

{

int

r[n+1][n+1]={0},

k;

for(int

i=1;

i<=n;

i++)

{

k=Find(i,

S);

r[k][0]++;

r[k][r[k][0]]=i;

}

for(i=1;

i<=n;

i++)

{

if(r[i][0]>0)

{

cout<<'{';

for(int

j=1;

j<r[i][0];

j++)

cout<<r[i][j]<<',';

cout<<r[i][r[i][0]]<<'}'<<endl;

}

}

}

void

main()

{

MFSET

S;

Equivalence(S);

print_MFSET(S);

}

十四、畫出下圖所示的森林經(jīng)轉(zhuǎn)換后所對應(yīng)的二叉樹,并指出在二叉樹中某結(jié)點為葉子結(jié)點時,所對應(yīng)的森林中結(jié)點應(yīng)滿足的條件。十五、已知森林F的先根序列為:ABCDEFGHIJKL,后根序列為:CBEFDGAJIKLH,試畫出森林F。提示:先畫出森林F所對應(yīng)的二叉樹B,然后再將B轉(zhuǎn)換為森林。十六、畫出表達(dá)式(A+B*C/D)*E+F*G所對應(yīng)的樹結(jié)構(gòu),并寫出該表達(dá)式的波蘭表示式和逆波蘭表示式。十七、利用逆波蘭表達(dá)式求一個四則混合元算的值。具體要求:定義二叉樹的型BTREE和位置的型position。實現(xiàn)二叉樹的基本操作。實現(xiàn)將一個四則混合運算轉(zhuǎn)換成二叉樹的函數(shù):BTREEconvert(char*express),其中參數(shù)express為四則混合運算表達(dá)式,返回值為生成的樹。實現(xiàn)計算四則混合運算的值的函數(shù):doublecomputer(BTREEbt),其中,參數(shù)bt為四則運算所對應(yīng)的樹,返回值為計算結(jié)果。提示:先求樹的的波蘭表達(dá)式,然后利用棧結(jié)構(gòu)計算表達(dá)式的值。在主函數(shù)中進(jìn)行測試,求2+3*(5+8)/4-5的值。#include"./stack.cpp"#include<iostream>#include<sstream>#defineMAXSIZE30usingnamespacestd;charmatch[]=">><<<>>>><<<>>>>>><>>>>>><>><<<<<=>>>>>><<<<<=";charopera[]="+-*/()@";constchar&Match(constchar&ch1,constchar&ch2){ inti=0,j=0; while(opera[i]!=ch1)i++; while(opera[j]!=ch2)j++; returnmatch[i*7+j];}classTNode{public: TNode(stringstr="",intb=0,TNode*l=NULL,TNode*r=NULL,TNode*p=NULL){ strcpy(id,str.c_str()); bit=b; left=l; right=r; parent=p; } TNode(constcharch,TNode*l=NULL,TNode*r=NULL,TNode*p=NULL){ id[0]=ch; id[1]=0; bit=0; left=l; right=r; parent=p; } constTNode&operator=(constTNode&tn){ strcpy(id,tn.id); bit=tn.bit; left=tn.left; right=tn.right; parent=tn.parent; } charid[MAXSIZE]; intbit; TNode*parent,*left,*right;};intReadExpr(char*str,char*expr,intstart,intbit,int&length){ length=0; if(str[start]==0){ expr[0]=0; return0; } elseif(str[start]=='*'||str[start]=='/'||str[start]=='('||str[start]==')'||str[start]=='@'){ expr[0]=str[start]; expr[1]=0; length=1; return2; } elseif(bit||isdigit(str[start])||str[start]=='.'){//readadigitstring intb=0; intk=0;//indexforexpr while(str[start]=='+'||str[start]=='-'){//readsign if(str[start]=='-')b++; start++; length++; } if(b%2)expr[k++]='-'; while(isdigit(str[start])||str[start]=='.'){ expr[k++]=str[start++]; length++; } expr[k]=0; return1; } elseif(str[start]=='+'||str[start]=='-'){//readaoper'+'or'-' intb=0; while(str[start]=='+'||str[start]=='-'){ if(str[start]=='-')b++; start++; length++; } if(b%2)expr[0]='-'; elseexpr[0]='+'; expr[1]=0; return2; } elsereturn-1;//error}TNode*Translate(conststring&str)//translateaexpressionstringtoaexpressiontree{ charsubstr[MAXSIZE]; Stack<char>cstk; Stack<TNode*>tstk; char*tempstr=newchar[str.length()+2]; intstart=0,bit=1; intt,length; strcpy(tempstr,str.c_str()); tempstr[str.length()]='@'; tempstr[str.length()+1]=0; cstk.push('@'); t=ReadExpr(tempstr,substr,start,bit,length); while(cstk.top()!='@'||substr[0]!='@'){ if(t==1){//isadigitstring TNode*np=newTNode(substr,1); tstk.push(np); bit=0; } elseif(t==2){//isaoper if(substr[0]=='(')bit=1; elsebit=0; chartch=cstk.top(); if(Match(tch,substr[0])=='>'){ TNode*right=tstk.top(); tstk.pop(); TNode*left=tstk.top(); tstk.pop(); TNode*np=newTNode(tch,left,right); left->parent=np; right->parent=np; tstk.push(np); cstk.pop(); continue; } elseif(Match(tch,substr[0])=='<')cstk.push(substr[0]); elsecstk.pop(); } start+=length; t=ReadExpr(tempstr,substr,start,bit,length); } delete[]tempstr;returntstk.top();}voidprint(TNode*root){ if(root->left){ print(root->left); print(root->right); cout<<root->id; } elsecout<<root->id;}voidprints(TNode*);doublesolve(TNode*);voidprintExpr(stringstr){ TNode*root=Translate(str); cout<<"后綴式:"; print(root); cout<<endl;cout<<"中綴式:"; prints(root); cout<<"="<<solve(root)<<endl;}voidprints(TNode*root)//將逆波蘭式用中綴形式打印出來{ if(root->left==NULL)cout<<root->id;//isaleaf elseif(root->parent==NULL){ prints(root->left); cout<<root->id; prints(root->right); } elseif(root->parent->left==root&&Match(root->id[0],root->parent->id[0])=='>'){ prints(root->left); cout<<root->id; prints(root->right); } elseif(root->parent->right==root){ if(Match(root->parent->id[0],root->id[0])=='<'||root->parent->id[0]=='+'){ prints(root->left); cout<<root->id; prints(root->right); } else{ cout<<"("; prints(root->left); cout<<root->id; prints(root->right); cout<<")"; } } else{ cout<<"("; prints(root->left); cout<<root->id; prints(root->right); cout<<")"; }}doublesolve(TNode*root){ if(root->left==NULL){ istringstreamin; in.str(root->id); doublevalue; in>>value; returnvalue; } else{ switch(root->id[0]){ case'+': returnsolve(root->left)+solve(root->right); case'-': returnsolve(root->left)-solve(root->right); case'*': returnsolve(root->left)*solve(root->right); case'/': returnsolve(root->left)/solve(root->right); } }}voidCheck(char*str)//判斷為帶符號且緊跟括號的情況,酌情在前面添"0-"{ intk=0,i=0; if(str[0]=='+'||str[0]=='-'){ intb=0; while(str[k]=='+'||str[k]=='-'){ if(str[k]=='-')b++; k++; } if(str[k]!='(')return; char*np=newchar[strlen(str)+3]; if(b%2){ np[0]='0'; np[1]='-'; memcpy(np+2,str+k,strlen(str)+1-k); memcpy(str,np,strlen(np)+1); } else{ memcpy(np,str+k,strlen(str)+1-k); memcpy(str,np,strlen(np)+1); } delete[]np; }} voidmain(){ charbuf[100]; while(1){ cin>>buf;Check(buf); printExpr(buf); }}//stack類#include<iostream>#include<string>usingnamespacestd;//classstacktemplate<typenameT>classSNode{public:SNode(){next=NULL;}SNode(constT&td,SNode<T>*p=NULL){data=td;next=p;}Tdata;SNode<T>*next;};template<typenameT>classStack{public:Stack(){pdata=NULL;length=0;}~Stack();boolisEmpty();boolpop();

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論