数据结构与算法习题第六章树与二叉树.docx

上传人:b****5 文档编号:7943815 上传时间:2023-01-27 格式:DOCX 页数:12 大小:74.87KB
下载 相关 举报
数据结构与算法习题第六章树与二叉树.docx_第1页
第1页 / 共12页
数据结构与算法习题第六章树与二叉树.docx_第2页
第2页 / 共12页
数据结构与算法习题第六章树与二叉树.docx_第3页
第3页 / 共12页
数据结构与算法习题第六章树与二叉树.docx_第4页
第4页 / 共12页
数据结构与算法习题第六章树与二叉树.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

数据结构与算法习题第六章树与二叉树.docx

《数据结构与算法习题第六章树与二叉树.docx》由会员分享,可在线阅读,更多相关《数据结构与算法习题第六章树与二叉树.docx(12页珍藏版)》请在冰豆网上搜索。

数据结构与算法习题第六章树与二叉树.docx

数据结构与算法习题第六章树与二叉树

第二部分习题精选

一、下面是有关二义树的叙述,请判断正误

()1.若二叉树用二叉链表作存贮结构,则在n个结点的二叉树链表中只有n—1个非空指针域。

()2.二叉树中每个结点的两棵子树的高度差等于1。

()3.二叉树中每个结点的两棵子树是有序的。

()4.二叉树中每个结点有两棵非空子树或有两棵空子树。

()5.二叉树中每个结点的关键字值大于其左非空子树(若存在的话)所有结点的关键字值,且小于其右非空子树(若存在的话)所有结点的关键字值。

()6.二叉树中所有结点个数是2k

()7.二叉树中所有结点,如果不存在非空左子树,则不存在非空右子树。

()&对于一棵非空二叉树,它的根结点作为第一层,则它的第i层上最多能有2*-1个结点。

()9•用二叉链表法(link-rlink)存储包含n个结点的二叉树,结点的2n个指针区域中有n+1个为空指针。

(V)10.具有12个结点的完全二叉树有5个度为2的结点。

二、填空

1.由3个结点所构成的二叉树有_种形态。

2.一棵深度为6的满二叉树有个分支结点和个叶子。

3.一棵具有257个结点的完全二叉树,它的深度为o

4.设一棵完全二叉树有700个结点,则共有个叶子结点。

5.设一棵完全二叉树具有1000个结点,则此完全二叉树有个叶子结点,有个

度为2的结点,有个结点只有非空左子树,有个结点只有非空右子树。

6•—棵含有n个结点的k叉树,可能达到的最大深度为,最小深度为—。

7.二叉树的基本组成部分是:

根(N)、左子树(L)和右子树(R)。

因而二叉树的遍历次

序有六种。

最常用的是三种:

前序法(即按NLR次序),后序法(即按次序)和

中序法(也称对称序法,即按LNR次序)。

这三种方法相互之间有关联。

若已知一棵二叉树的前序序列是BEFCGDH,中序序列是FEBGCHD,则它的后序序列必是。

8.中序遍历的递归算法平均空间复杂度为o

9.用5个权值{3.2,4.5,1}构造的哈夫曼(Huffman)树的带权路径长度是。

三、单项选择题

()1.不含任何结点的空树°

(A)是一棵树;(B)是一棵二叉树;

(C)是一棵树也是一棵二叉树;(D)既不是树也不是二叉树

()2.二叉树是非线性数据结构,所以°

(A)它不能用顺序存储结构存储;(B)它不能用链式存储结构存储;

(C)顺序存储结构和链式存储结构都能存储;

(D)顺序存储结构和链式存储结构都不能使用

()3.具有n(n>0)个结点的完全二叉树的深度为。

(A)「log2(n)1(B)Llog2(n)J(C)Llog2(n)J+l(I))「log2(n)+1]

()4.把一棵树转换为二叉树后,这棵二叉树的形态是o

(A)唯一的(B)有多种

(C)有多种,但根结点都没有左孩子(D)有多种,但根结点都没有右孩子

四、算法设计题

1•编写递归算法,计算二叉树中叶子结点的数目。

2.写出求二叉树深度的算法,先泄义二叉树的抽象数据类型。

或编写递归算法,求二叉树中以元素值为x的结点为根的子树的深度。

3.编写按层次顺序(同一层自左至右)遍历二叉树的算法。

或:

按层次输岀二叉树中所有结点:

4.已知一棵具有n个结点的完全二叉树被顺序存储于一维数组A中,试编写一个算法打印出编号为i的结点的双亲和所有的孩子。

5.编写算法判别给建二叉树是否为完全二叉树。

6.假设用于通信的电文仅由8个字母组成,字母在电文中出现的频率分别为0.07,0.19,0.02,0.06,0.32,0.03,0.21,0.10。

试为这8个字母设计哈夫曼编码。

使用0〜7的二进制表示形式是另一种编码方案。

对于上述实例,比较两种方案的优缺点。

习题精选答案

1.(V)2.(X)3.(J)4.(X)5.(X)

6.(X)7.(X)&(X)9.(V).10.(V)

1.52.31323.94.3505.50049910

6.n27.LRNFEGHDCB8.O(n)9.33

三、单项选择题

1.(C)2・(C)3.(C)4・(A)

四、1.解:

思路:

输岀叶子结点比较简单,用任何一种遍历递归算法,凡是左右指针均空者,则为叶子,将其打印出来。

法一:

核心部分为:

DLR(liuyu*root)严中序遍历递归函数*/

{if(root!

=NULL)

{if((root->lchild==NULL)&&(root->rchild==NULL)){sum++;printf(M%d\n,\root->data);}

DLR(root->lchild);

DLR(root->rchild);}

return(O);

}

法二:

intLcafCount_BiTree(BitreeT)〃求二叉树中叶子结点的数目

{

if(!

T)return0;//空树没有叶子

elseif(!

T->lchi!

d&&!

T->rchild)return1;〃叶子结点

elsereturnLeaf_Count(T->lchild)+Lcaf_Count(T->rchiId)y/左子树的叶子数加

上右子树的叶子数

)//LeafCount_BiTree

①打印叶子结点值(并求总数)

思路:

先建树,再从遍历过程中打印结点值并统计。

步骤1键盘输入序列12,8,17,11,16,2,13,9,21,4,构成一棵二叉排序树。

叶子结点值应该是4,9,13,21,总数应该是4.

111621

//

4913

编程:

生成二叉树排序树之后,再中序遍历排序查找结点的完整程序如下:

说明部分为:

#includc

#includc

typcdefstnictliuyufintdata;stnictliuyu*lchild,*rchild;}test;

liuyu*root;

intsum=O;intm=sizeof(test);

voidinsert_data(intx)/*如何生成二叉排序树?

参见教材P43C程序*/

{liuyu*p,*q,*s;

s=(test*)malloc(m);

s->data=x;

s->lchild=NULL;

s->rchild=NULL;

if(!

root){root=s;return;}

p=root;

while(p)/*如何接入二叉排序树的适当位巻*/

{q=p;

if(p->data=x){printf("dataalreadyexist!

\nH);return;}

elseif(xdata)p=p->lchild;elsep=p->rchild;

}

if(xdata)q->lchild=s;

elseq->rchild=s;

}

DLR(liuyu*root)/*中序遍历递归函数*/

{if(root!

=NULL)

{if((root->lchild==NULL)&&(root->rchild==NULL)){sum++;printf(H%d\n'\root->data);}

DLR(root->lchild);

DLR(root->rchild);}

return(O);

}

mainO/*先生成二叉排序树,再调用中序遍历递归函数进行排序输出*/

{inti.x;

i=l;

root=NULL;/*千万别忘了赋初值给root!

*/

do{printf(HpIeasei叩utdata%d:

uj);

i++;

scanf(規d”,&x);八从键盘采集数据,以4999表示输入结朿引

if(x==-9999){

DLR(root);

printf(M\nNowoutputcountvalue:

%d\n,\sum);

return(O);}

elseinsert_data(x);}/*调用插入数据元素的函数*/

while(x!

=-9999);

return(O):

}

2.答:

设计思路:

只査后继链表指针,若左或右孩子的左或右指针非空,则层次数加1:

否则函数返回。

但注意,递归时应当从叶子开始向上计数,否则不易确左层数。

intdepth(liuyu*root)/*统计层数*/

{intd.p;戶注意每一层的局部变量d.p都是各自独立的*/

p=o:

if(root=NULL)return(p);/*找到叶子之后才开始统讣

else{

d=dcpth(root->lchild);

if(d>p)p=d;/*向上回朔时,要挑出左右子树中的相对大的那个深度值*/

d=depth(root->rchild);

if(d>p)p=d;

}

p=p+l;

rcturn(p);

}

法二:

intGet_Sub_Dcpth(BitreeT.intx)〃求二叉树中以值为x的结点为根的子树深度

{

if(T->data=x)

{

printf(H%d\ir\GeLDepth(T));//找到了值为x的结点,求其深度

exit1;

else

{

if(T->lchild)Get_Sub_Depth(T->lchild?

x);

if(T->rchild)Get_Sub_Depth(T->rchild.x);〃在左右子树中继续寻找

}

)//Get_Sub_Depth

intGet_Depth(BitreeT)〃求子树深度的递归算法

if(!

T)return0;

else

{

m=Get_Depth(T->lchild);

n=Get_Depth(T->rchild);

return(m>n?

m:

n)+l;

}

)//Get_Depth

步骤2:

执行求深度的函数,并打印统汁岀来的深度值。

完整程序如下:

#includc

#includc

typcdefstnictliuyu{intdata;stnictliuyu*lchild,*rchild;}test;

liuyu*root;

intsum=0;intm=sizeof(test);

voidinsert_data(intx)/*如何生成二叉排序树?

参见教材P43C程序*/

{liuyu*p,*q,*s;

s=(test*)malloc(m);

s->data=x;

s->lchild=NULL;

s->rchild=NULL;

if(!

root){root=s;return;}

p=root;

while(p)/*如何接入二叉排序树的适当位巻*/

{q=p;

if(p->data=x){printf("dataalreadyexist!

\nH);return;}

elseif(xdata)p=p->lchild;elsep=p->rchild;

}

if(xdata)q->lchild=s;

elseq->rchild=s;

}

intdepth(liuyu*root)/*统计层数*/

{intd.p;戶注意每一层的局部变量d.p都是各自独立的*/

p=0;

if(root=NULL)return(p);/*找到叶子之后才开始统讣*/

else{

d=depth(root->lchild);

if(d>p)p=d;/*向上回朔时,要挑岀左右子树中的相对大的那个深度值*/

d=dcpth(root->rchild);

if(d>p)p=d;

p=p+l;

return(p);

voidmain()八先生成二叉排序树,再调用深度遍历递归函数进行统计并输岀

*/

{inti,x;

i=l;

root=NULL;/*千万别忘了赋初值给root!

*/

do{printf(npleasei叩utdata%d:

Hj);

i++;

scanf(H%d\&x);戶从键盘采集数据,以・9999表示输入结束旬

if(x==-9999){

printf(M\iiNowoutputdepthvalue=%d\n,\depth(root));return:

}elseinsert_data(x);}/*调用插入数据元素的函数*/

while(x!

=-9999);

return;}

3.解:

思路:

既然要求从上到下,从左到右,则利用队列存放各子树结点的指针是个好办法。

这是一个循环算法,用while语句不断循环,直到队空之后自然退岀该函数。

技巧之处:

当根结点入队后,会自然使得左、右孩子结点入队,而左孩子出队时又会立即使得它的左右孩子结点入队,……以此产生了按层次输出的效果。

level(liuyu*T)

/*liuyu*T,*p,*q[100];假设max已知*/

{intfj;

f=0;r=0;/*置空队引

r=(r+l)%max;

q[r]=T;/*根结点进队*/

while(f!

=r)/*队列不空*/

{f=(f+l%max);

p=q[f];/*出队引

primf(”%d”p>data);八打印根结点牝/

if(p->lchild){r=(r+1)%max:

q[r]=p->lchild:

}/*若左子树不空,则左子树进队*/

if(p->rchild){r=(r+1)%max;q[r]=p->rchild;}/*若右子树不空,则右子树进队*/

}return(O);

}

法二:

voidLayerOrder(BitreeT)〃层序遍历二叉树

{

InitQueue(Q);//建立工作队列

EnQueue(Q,T);

while(!

QueueEnipty(Q))

{

DeQucue(Q,p);

visit(p);

if(p->lchild)EnQueue(Q.p->lchild);

if(p->rchild)EnQueue(Q,p->rchild);

}

}//LayerOrder

可以用前而的函数建树,然后调用这个函数来输出。

完整程序如下(已上机通过)

#includc

#includc

#dcfinemax50

typcdefstnictliuyufintdata;stnictliuyu*lchild,*rchild;}test;

liuyu*root,*p,*q[max];

intsum=0;intm=sizeof(test);

voidinsert_data(intx)/*如何生成二叉排序树?

参见教材P43C程序*/

{liuyu*p,*q,*s;

s=(test*)malloc(m);

s->data=x;s->lchild=NULL;s->rchild=NULL;

if(!

root){root=s;return;}

p=root;

while(p)/*如何接入二叉排序树的适当位巻*/

{q=p;

if(p->data=x){printf("dataalreadyexist!

\nH);return;}

elseif(xdata)p=p->lchild;elsep=p->rchild;

}

if(xdata)q->lchild=s;

elseq->rchild=s;

}

level(liuyu*T)

/*liuyu*T,*p,*q[100];假设max已知*/

{intf,r;

f=0;r=0;/*置空队引

r=(r+l)%max:

q[r]=T;/*根结点进队*/

while(f!

=r)/*队列不空*/

{f=(f+l%max);

p=q[f];/*出队勺

primf(”%d”p>data);八打印根结点*/

if(p->lchild){r=(r+1)%max;q[r]=p->lchild:

}/*若左子树不空,则左子树进队*/

if(p->rchild){r=(r+1)%max;q[r]=p->rchild:

}/*若右子树不空,则右子树进队*/

return(O);

}

voidmain()严先生成二叉排序树,再调用深度遍历递归函数进行统计并输出

*/

{inti,x;

i=l;

root=NULL;/*千万别忘了赋初值给root!

*/

do{printf(npleasei叩utdata%d:

\i);

i++;

scanf(H%d\&x);戶从键盘采集数据,以・9999表示输入结束旬

if(x==-9999){

printf(M\iiNowoutputdatavalue:

\nM,level(root));return;}

elseinsert_data(x);}/*调用插入数据元素的函数*/

while(x!

=-9999);

return;}

4.答:

首先,由于是完全二叉树,不必担心中途会出现孩子为null的情况。

其次分析:

结点i的左孩子为2i,右孩子为2i+l;直接打印即可。

Printf(fcfcLeft_cliild=\%d,v[2*i].data;"Right_child=二%d,v[2*卄1].data;);

但苴双亲是i/2,需先判断i为奇数还是偶数。

若i为奇数,则应当先i-,然后再除以

2。

If(i/2!

=0)i-;

PrmtfC€Parents=\%d,v[i/2].data;);

5.答:

imIsFull_Bitrcc(BitrccT)〃判断二叉树是否完全二叉树,是则返回1,否则返回0

{

InitQueue(Q);

flag=O;

EnQueue(Q,T);〃建立工作队列

while(!

QueueEmpty(Q))

{

{

DeQueue(Q.p);

if(!

p)flag=l;

elseif(flag)return0;

else

{

EnQueue(Q.p->lchild);

EnQucuc(Q,p->rchild);〃不管孩子是否为空,都入队列

}

}//while

return1;

}//IsFulLBitree

分析:

该问题可以通过层序遍历的方法来解决.与6.47相比,作了一个修改,不管当前结点是否有左右孩子,都入队列•这样当树为完全二叉树时,遍历时得到是一个连续的不包含空指针的序列•反之,则序列中会含有空指针.

6、解:

方案1:

哈夫曼编码先将槪率放大100倍,以方便构造哈夫曼树。

w二{7,1926,32,3,21,10},按哈夫曼规则:

【[(2,3〉,

方案比较:

方案1的WPL=2(0.19+0.32+0.21)+4(0.07+0.06+0.10)+5(0.02+0.03)=1.44+0.92+0.25=2.61

方案2的WPL=3(0.19+0.32+0.21+0.07+0.06+0.10+0.02+0.03)=3

结论:

哈夫曼编码优于等长二进制编码

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 韩语学习

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1