《数据结构与算法》第二部分 习题精选
一、下面是有关二叉树的叙述,请判断正误
( )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.(C4.(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小时内删除。