国产最新a级毛片无码专区_综合亚洲欧美日韩久久精品_日本成年片在线观看66_一本到九九av电影_一级毛片免费网站播放_国内精品久久人无码大片_国产人成视频99在线观看_欧美不卡在线一本二本_国产亚洲电影av_可以免费看黄色软件

知ing

數(shù)據(jù)結(jié)構(gòu)實用教程(第二版)

徐孝凱 編 / 清華大學(xué)出版社

誰南 上傳

查看本書

1.

解:略

2.

解:略

3.已知一棵度為m的樹中有n1個度為1的結(jié)點,n2個度為2的結(jié)點

,.....,nm個度為m的結(jié)點,問樹中有多少個葉子結(jié)點?

解:

設(shè)葉子結(jié)點數(shù)為n0,則樹中結(jié)點數(shù)和總度數(shù)分別為

結(jié)點數(shù)=n0+n1+n2+...+nm

總度數(shù)=n1+2n2+...+m×nm

根據(jù)樹的性質(zhì)1可知,結(jié)點數(shù)等于總度數(shù)加1,所以得到

m

n0=1+Σ((i-1)×ni)

i=2

4.畫出由三個結(jié)點a,b,c組成的所有不同結(jié)構(gòu)的二叉樹,共有多少種不同的結(jié)構(gòu)?每一種結(jié)

構(gòu)又對應(yīng)多少種不同的值的排列次序?

解:

由三個結(jié)點a,b,c組成的所有不同結(jié)構(gòu)的二叉樹如下圖所示,共有5種不同的結(jié)構(gòu),每一

種結(jié)構(gòu)對應(yīng)6種不同的值的排列次序。

a a a a a

/ \ / / \ \

b c b b b b

/ \ / \

c c c c

5.已知一棵具有n個結(jié)點的完全二叉樹被順序存儲于一維數(shù)組的A[1]~A[n]元素中,試編寫一

個算法打印出編號為i的結(jié)點的雙親和所有孩子。

解:

void Request(int a[],int n,int i)

//從數(shù)組A中打印出編號為i的結(jié)點的雙親和孩子

{

if(i>n){

cerr<<"編號為"<<i<<"的結(jié)點不存在!"<<end1;

exit(1);

}

cout<<"current element:"<<A[i]<<end1;

int j=i/2; //下標為j的結(jié)點是下標為i結(jié)點的雙親

if(j>0)

cout<<"parent:"<<A[j]<<end1;

else

cout<<"樹根結(jié)點沒有雙親結(jié)點!"<<end1;

if(2*i<n){

cout<<"left child:"<<A[2*i]<?end1;

cout<<"right child:"<<A[2*i+1]<<end1;

}

else if(2*i==n){

cout<<"left child:"<<A[2*i]<<end1;

cout<<"no right child!"<<end1;

}

else

cout<<"no children!"<<end1;

}

6.已知一棵二叉樹如下圖所示,試分別畫出它的不帶雙親指針的鏈接存儲結(jié)構(gòu)的示意圖和

存儲于數(shù)組的鏈接存儲映像(假定按層次依次為各結(jié)點分配下標位置)。

解:

25

/ \

16 37

/ / \

8 30 48

/ \ \

28 32 60

/ \ \

26 29 35

在數(shù)組中的二叉樹存儲映像如下所示。

0 1 2 3 4 5 6 7 8 9 10 11 12 13 ...BTreeMaxSize

data 25 16 37 8 30 48 28 32 60 26 29 35

left 1 2 4 5 0 7 0 10 0 0 0 0 0

right 13 3 0 6 0 8 9 11 12 0 0 0 0 14 0

7.寫出對圖5-3所示的二叉樹分另按前序、中序、后序遍歷時得到的結(jié)點序列。

解:

前序遍歷為 25,16,8,37,30,28,26,29,32,35,48,60

中序遍歷為 8,16,25,26,28,29,30,32,35,37,48,60

后序遍歷為 8,16,26,29,28,35,32,30,60,48,37,25

8.寫出對二叉樹進行中序遍歷的非遞歸算法。

解:

void InorderN(BTreeNode*BT)

//對二叉樹進行中序遍歷的非遞歸算法

{

BTreeNode* s[10];//定義用于存儲結(jié)點指針的棧

int top=-1;定義棧頂指針并賦初值使s棧為空

BTreeNode* p=BT;//定義指針p并使樹根指針為它的初值

while(top!=-1||p!=NULL)

{//當棧非空或p指針非空時執(zhí)行循環(huán)

while(p!=NULL){

top++;

s[top]=p;

p=p->left;

}

if(top!=-1){

p=s[top];

top--;

cout<<p->data<<'';

p=p->right;

}

}

}

9.編寫一算法,求出一棵二叉樹中所有結(jié)點數(shù)和葉子結(jié)點,假定分別用變參C1和C2統(tǒng)計所

有結(jié)點數(shù)和葉子結(jié)點數(shù),初值均為0。

解:

void Count(BTreeNode* BT,int& C1,int& C2)

//分別統(tǒng)計出二叉樹中所有結(jié)點數(shù)和葉子結(jié)點數(shù)

{

if(BT!=NULL){

C1++;//統(tǒng)計所有結(jié)點

if(BT->left==NULL&&BT->right==NULL)

C2++; //統(tǒng)計葉子結(jié)點數(shù)

Count(BT->left,C1,C2);

Count(BT->right,C1,C2);

}

}

10.編寫具有下列功能的每個函數(shù):

把在內(nèi)存中生成的一棵二叉樹寫入到一個磁盤文件中,該函數(shù)聲明為

void WriteFile(char* fname,BTreeNode*BT);

解:

根據(jù)從鍵盤上輸入的一棵二叉樹廣義表表示建立一棵二叉樹bt;

把bt二叉樹寫入到磁盤文件"a:xxkl.dat"中;

把磁盤文件"a:xxkl.dat"中保存的二叉樹恢復(fù)到內(nèi)存中,并由bt指向樹根結(jié)點;

以廣義表的形式輸出以bt為樹根指針的二叉樹。

解:

寫出先根遍歷得到的結(jié)點序列;

寫出按層遍歷得到的結(jié)點序列;

畫出轉(zhuǎn)換后得到的二叉樹和二叉鏈表。

解:

void WriteFile(char* fname,BTreeNode*BT)

//把由BT指針所指二叉樹按照層次遍歷的次序存儲結(jié)點到文件fname中

{

ofstream ofs(fname,ios::binary);

//把由fname所指字符串作為文件名的文件定義為輸出文件流ofs,并按二進制方

//式打開

LinkQueue HQ;InitQueue(HQ);

//定義一個鏈接隊列并進行初始化,該鏈接隊列中結(jié)點值的類型應(yīng)為二叉樹結(jié)點

//的類型

BTreeNode* p;

if(BT!==NULL)QInsert(HQ,BT){

//將樹根指針插入到隊列中

while(! QueueEmpty(HQ)){

p=QDelete(HQ);

//從隊列中刪除一個元素并賦給指針

ofs.write((char*)p,sizeof(*p));

//把p指針所指結(jié)點寫入到文件中

if(p->left!=NULL)QInsert(HQ,p->left);

//若p結(jié)點存在左孩子,則左孩子指計入隊

if(p->right!=NULL)QInsert(HQ,p->right);

//若p結(jié)點存在右孩子,則右孩子指計入隊

}

ofs.closs();//關(guān)閉文件流對象所對應(yīng)的文件

}

2.把存儲到磁盤文件中的一棵二叉樹恢復(fù)到內(nèi)存存中,該函數(shù)聲明為

void WriteFile(char* fname,BTreeNode*&BT);

解:

void WriteFile(char* fname,BTreeNode*&BT)

//把fname文件中按層掃描存儲的二叉樹恢復(fù)到內(nèi)存中,并由引用指針BT指向樹根結(jié)點

{

ifstream ifs(fname,ios::in | ios::nocreate | ios::binary);

//把fname文件定義為輸入文件流ifs,并按二進制方式打開

if(! ifs){cout<<"File not open!"<<end1;exit(1);}

LinkQueue HQ; InitQueue(HQ);

//定義一個鏈接隊列并進行初始化

BTreeNode *p1,*p2;

int b=sizeof(*p1);

//把二叉樹結(jié)點的大小賦給b,作為讀取文件的基本單位

ifs.seekg(0,ios::end);

//把文件指針移到結(jié)束位置

int n=ifs.tellg()/b;

//求出文件中所存二叉樹的結(jié)點數(shù)并賦給n

ifs.seekg(0);

//將文件指針移到文件開始位置,以便從頭開始讀取每個結(jié)點

if(n==0){ifs.close();BT=NULL;return;}

//如果文件為空,則把BT置空后返回,用文件中的第一個結(jié)點構(gòu)成樹根結(jié)點并將

//該結(jié)點指針插入隊列中

p1=new BTreeNode;

ifs.read((char*)p1,b);

BT=p1;

QInsert(HQ.p1);

n--;

//依次用文件中的每個結(jié)點構(gòu)成新結(jié)點并把它插入到雙親結(jié)點的左孩子或右孩子位置

while(n)

{ //當讀完文件中的結(jié)點后循環(huán)結(jié)束

p2=QDelete(HQ);//從隊列中刪除隊首元素并賦給p2

if(p2->left!=0)

{//需要給p2結(jié)點添加左孩子,并使左孩子指針進隊

p1=new BTreeNode;

ifs.read((char*)p1,b);

p2->left=p1;

Qinsert(HQ,p1);

n--;

}

if(p2->right!=0)

{ //需要給p2結(jié)點添加右孩子,并使右孩子指針進隊

p1=new BTreeNode;

ifs.read((char*)p1,b);

p2->right=p1;

QInsert(HQ,p1)

n--;

}

}

ifs.close();//關(guān)閉ifs對應(yīng)的磁盤文件

}

11.編寫一個完整的程序?qū)崿F(xiàn)下列功能:

#include<iostream.h>

#include<fstream.h>

#include<strstrea.h>

#include<stdlib>

struct BTreeNode {//定義二叉樹結(jié)點類型

char data; //定義結(jié)點值的類型為整型

BTreeNode *left;

BTreeNode *right;

};

typedef BTreeNode* ElemType;//定義鏈接隊列中結(jié)點值的類型為二叉樹結(jié)點的指針類型

struct LNode{ElemType data;LNode* next;};

//定義鏈接隊列中結(jié)點的類型

struct LinkQueue{LNode* front;LNode*rear;};

//定義一個鏈接隊列的存儲類型

#include"linkqueue.h"http://包含對鏈接隊列的各種運算

#include"btree.h"http://包含二叉樹的各種運算

void WriteFile(char* fname,BTreeNode* BT)

//把由BT指針所指二叉樹按照層次遍歷的次序存儲結(jié)點到文件fname中

{

//函數(shù)體略

}

void ReadFile(char* fname,BTreeNode*&BT)

//把fname文件中按層掃描存儲的二叉樹恢復(fù)到內(nèi)存中,并由引用指針BT

//指向樹根結(jié)點

{

//函數(shù)體略

}

void main()

{

BtreeNode *bt;

InitBTree(bt);

while(1)

{

cout<<"功能菜單:"<<end1;

cout<<'\t'<<"1.建立二叉樹"<<end1;

cout<<'\t'<<"2.二叉樹存盤"<<end1;

cout<<'\t'<<"3.由文件恢復(fù)二叉樹"<<end1;

cout<<'\t'<<"4.以廣義表形式輸出二叉樹"<<end1;

cout<<'\t'<<"5.結(jié)束程序運行"<<end1;

cout<<end1;

int m;

cout<<"輸入你的選擇(1-5):";

do cin>>m;while(m<1||m>5);

switch(m){

case 1:

char a[50];

cout<<"輸入以'@'字符作為結(jié)束符的二叉樹廣義表表示:"<<end1;

cin>>ws;//跳過鍵盤輸入緩沖區(qū)中的空白字符

cin.getline(a,50);

createBTree(bt,a);

break;

case 2:

WriteFile("a:xxkl.dat",bt);

break;

case 3:

ReadFile("a:xxkl.dat",bt);

break;

case 4:

PrintBTree(bt);cout<<end1;

break;

default;

break;

}

if(m==5)break;

}

}

12.對于圖5-16所示的樹:

13.假定一棵樹采用標準形式存儲,試寫出廣義表形式輸出樹的算法。

解:

void printGTree(GTreeNode* GT)

//以廣義表形式輸出按標準方式存儲的三叉樹

{

if(GT!=NULL){//若樹不為空則進行如下處理

cout<<GT->data<<'';//輸出根結(jié)點的值

if(GT->t[0]||GT->t[1]||GT->t[2]){

cout<<'(';

printGTree(GT->t[0]);//輸出第一棵子樹

cout<<',';

printGTree(GT->t[1]);//輸出第二棵子樹

cout<<',';

printGTree(GT->t[2]);//輸出第三棵子樹

cout<<')';

}

}

}

14.假定采用標準形式存儲,試寫出求其深度的算法。

解:

int GTreeDepth(GTreeNode* GT)

//求一棵普通樹的深度

{

if(GT==NULL)//空樹的深度為0

return 0;

else{

int max=0;//用來保存子樹中的最大深度

for(int i=0;i<3;i++){

int d=GTreeDepth(GT->t[i]);

//計算出一棵子樹的深度并賦給變量d

if(d>max)max=d;

}

return max+1; //返回樹的深度,它等于子樹的最大深度加1

}

}

10.在一份電文中共使用五種字符:a、b、c、d、e ,它們的出現(xiàn)頻率依次為4、7、5、2、9

,試畫出對應(yīng)的編碼哈夫曼樹(請按照左子樹根結(jié)點的權(quán)小于等于右子樹根結(jié)點的權(quán)的次序構(gòu)

造),求出每個字符的哈夫曼編碼,并求出傳送電文的長度。

解:

五種字符的哈夫曼編碼依次為001,10,00,010,11。傳送電文的總長度為60。


查看更多