《数据结构与算法》第二部分 习题精选
一、下面是有关二叉树的叙述,请判断正误
( )1. 若二叉树用二叉链表作存贮结构,则在n个结点的二叉树链表中只有n—1个非空指针域。
( )2.二叉树中每个结点的两棵子树的高度差等于1。
( )3.二叉树中每个结点的两棵子树是有序的。
( )4.二叉树中每个结点有两棵非空子树或有两棵空子树。
( )5.二叉树中每个结点的关键字值大于其左非空子树(若存在的话)所有结点的关键字值,且小于其右非空子树(若存在的话)所有结点的关键字值。
( )6.二叉树中所有结点个数是2k-1-1,其中k是树的深度。
( )7.二叉树中所有结点,如果不存在非空左子树,则不存在非空右子树。
( )8.对于一棵非空二叉树,它的根结点作为第一层,则它的第i层上最多能有2i—1个结点。
( )9.用二叉链表法(link-rlink)存储包含n个结点的二叉树,结点的2n个指针区域中有n+1个为空指针。
( √ )10. 具有12个结点的完全二叉树有5个度为2的结点。
二、填空
1. 由3个结点所构成的二叉树有 种形态。
2. 一棵深度为6的满二叉树有 个分支结点和 个叶子。
3. 一棵具有257个结点的完全二叉树,它的深度为 。
4.设一棵完全二叉树有700个结点,则共有 个叶子结点。
5. 设一棵完全二叉树具有1000个结点,则此完全二叉树有 个叶子结点,有 个度为2的结点,有 个结点只有非空左子树,有 个结点只有非空右子树。
6.一棵含有n个结点的k叉树,可能达到的最大深度为 ,最小深度为 。
7. 二叉树的基本组成部分是:根(N)、左子树(L)和右子树(R)。因而二叉树的遍历次序有六种。最常用的是三种:前序法(即按N L R次序),后序法(即按 次序)和中序法(也称对称序法,即按L N R次序)。这三种方法相互之间有关联。若已知一棵二叉树的前序序列是BEFCGDH,中序序列是FEBGCHD,则它的后序序列必是 。
8.中序遍历的递归算法平均空间复杂度为 。
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) (B) log2(n) (C) log2(n) +1 (D) log2(n)+1
( )4.把一棵树转换为二叉树后,这棵二叉树的形态是 。
(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.(√)2.(×) 3.(√) 4.(×) 5.(×)
6.(×) 7.(×) 8.(×)9.( √ )。10.( √ )
二
1.5 2. 31 32 3.9 4. 350 5. 500 499 1 0
6. n 2 7. L R N F E G H D C B 8. 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("%d\n",root->data);}
DLR(root->lchild);
DLR(root->rchild); }
return(0);
}
法二:
int LeafCount_BiTree(Bitree T)//求二叉树中叶子结点的数目
{
if(!T) return 0; //空树没有叶子
else if(!T->lchild&&!T->rchild) return 1; //叶子结点
else return Leaf_Count(T->lchild)+Leaf_Count(T->rchild);//左子树的叶子数加
上右子树的叶子数
}//LeafCount_BiTree
1打印叶子结点值(并求总数)
思路:先建树,再从遍历过程中打印结点值并统计。
步骤1 键盘输入序列12,8,17,11,16,2,13,9,21,4,构成一棵二叉排序树。叶子结点值应该是4,9, 13, 21, 总数应该是4.
12
7 17
2 11 16 21
4 9 13
编程: 生成二叉树排序树之后,再中序遍历排序查结点的完整程序如下:
说明部分为:
#include <stdio.h>
#include <stdlib.h>
typedef struct liuyu{int data;struct liuyu *lchild,*rchild;}test;
liuyu *root;
int sum=0;int m=sizeof(test);
void insert_data(int x) /*如何生成二叉排序树?参见教材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("data already exist! \n");return;}
else if(x<p->data)p=p->lchild; else p=p->rchild;
}
if(x<q->data)q->lchild=s;
else q->rchild=s;
}
DLR(liuyu *root) /*中序遍历 递归函数*/
{if(root!=NULL)
{if((root->lchild==NULL)&&(root->rchild==NULL)){sum++; printf("%d\n",root->data);}
DLR(root->lchild);
DLR(root->rchild); }
return(0);
}
main() /*先生成二叉排序树,再调用中序遍历递归函数进行排序输出*/
完全二叉树算法{int i,x;
i=1;
root=NULL; /*千万别忘了赋初值给root!*/
do{printf("please input data%d:",i);
i++;
scanf("%d",&x); /*从键盘采集数据,以-9999表示输入结束*/
if(x==-9999){
DLR(root);
printf("\nNow output count value:%d\n",sum);
return(0); }
else insert_data(x);} /*调用插入数据元素的函数*/
while(x!=-9999);
return(0);}
2. 答;设计思路:只查后继链表指针,若左或右孩子的左或右指针非空,则层次数加1;否则函数返回。
但注意,递归时应当从叶子开始向上计数,否则不易确定层数。
int depth(liuyu*root) /*统计层数*/
{int d,p; /*注意每一层的局部变量d,p都是各自独立的*/
p=0;
if(root==NULL)return(p); /*到叶子之后才开始统计*/
else{
d=depth(root->lchild);
if(d>p) p=d; /*向上回朔时,要挑出左右子树中的相对大的那个深度值*/
d=depth(root->rchild);
if(d>p)p=d;
}
p=p+1;
return(p);
}
法二:
int Get_Sub_Depth(Bitree T,int x)//求二叉树中以值为x的结点为根的子树深度
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论