第六次作业
| 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/qdu/DS2020 |
|---|---|
| 这个作业要求在哪里 | https://edu.cnblogs.com/campus/qdu/DS2020/homework/11430 |
| 这个作业的目标 | <掌握二叉树的基本特性;掌握二叉树的先序、中序、后序的递归遍历算法;理解二叉树的先序、中序、后序的非递归遍历算法;通过求二叉树的深度、叶子结点数和层序遍历等算法,理解二叉树的基本特性> |
| 学号 | 2018204248 |
| 一、实验目的 | |
| 1、掌握二叉树的基本特性 | |
| 2、掌握二叉树的先序、中序、后序的递归遍历算法 | |
| 3、理解二叉树的先序、中序、后序的非递归遍历算法 | |
| 4、通过求二叉树的深度、叶子结点数和层序遍历等算法,理解二叉树的基本特性 |
二、实验预习
说明以下概念
1、二叉树:二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个结点 。
2、递归遍历:由于二叉树所具有的递归性质,一棵非空的二叉树可以看作是由根节点、左子树和右子树3部分构成,因为若能依次遍历这3部分的信息,也就遍历了整个二叉树。按照左子树的遍历在右子树的遍历之前进行的约定,根访问根节点位置的不同,可以得到二叉的前序、中序、后序3种遍历方法。
3、非递归遍历:不采用递归的方式对二叉树进行遍历,要采用栈去模拟实现。
4、层序遍历:设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。
三、实验内容和要求
1、阅读并运行下面程序,根据输入写出运行结果,并画出二叉树的形态。
#include<stdio.h>
#include<malloc.h>
#include<iostream>
#include<conio.h>
#define MAX 20
typedef struct BTNode{ /*节点结构声明*/
char data ; /*节点数据*/
struct BTNode *lchild;
struct BTNode *rchild ; /*指针*/
}*BiTree;
void createBiTree(BiTree *t){ /* 先序遍历创建二叉树*/
char s;
BiTree q;
printf("\nplease input data:(exit for #)");
s=getche();
if(s=='#'){*t=NULL; return;}
q=(BiTree)malloc(sizeof(struct BTNode));
if(q==NULL){printf("Memory alloc failure!"); exit(0);}
q->data=s;
*t=q;
createBiTree(&q->lchild); /*递归建立左子树*/
createBiTree(&q->rchild); /*递归建立右子树*/
}
void PreOrder(BiTree p){ /* 先序遍历二叉树*/
if ( p!= NULL ) {
printf("%c", p->data);
PreOrder( p->lchild ) ;
PreOrder( p->rchild) ;
}
}
void InOrder(BiTree p){ /* 中序遍历二叉树*/
if( p!= NULL ) {
InOrder( p->lchild ) ;
printf("%c", p->data);
InOrder( p->rchild) ;
}
}
void PostOrder(BiTree p){ /* 后序遍历二叉树*/
if ( p!= NULL ) {
PostOrder( p->lchild ) ;
PostOrder( p->rchild) ;
printf("%c", p->data);
}
}
void Preorder_n(BiTree p){ /*先序遍历的非递归算法*/
BiTree stack[MAX],q;
int top=0,i;
for(i=0;i<MAX;i++) stack[i]=NULL;/*初始化栈*/
q=p;
while(q!=NULL){
printf("%c",q->data);
if(q->rchild!=NULL) stack[top++]=q->rchild;
if(q->lchild!=NULL) q=q->lchild;
else
if(top>0) q=stack[--top];
else q=NULL;
}
}
void release(BiTree t){ /*释放二叉树空间*/
if(t!=NULL){
release(t->lchild);
release(t->rchild);
free(t);
}
}
int main(){
BiTree t=NULL;
createBiTree(&t);
printf("\n\nPreOrder the tree is:");
PreOrder(t);
printf("\n\nInOrder the tree is:");
InOrder(t);
printf("\n\nPostOrder the tree is:");
PostOrder(t);
printf("\n\n先序遍历序列(非递归):");
Preorder_n(t);
release(t);
return 0;
}
输入:
ABC##DE#G##F###
运行结果:

二叉树形态:

2、在上题中补充求二叉树中求结点总数算法(提示:可在某种遍历过程中统计遍历的结点数),并在主函数中补充相应的调用验证正确性。
算法代码:
int PreOrder_num(BiTree p){
int j=0;
BiTree stack[MAX],q;
int top=0,i;
for(i=0;i<MAX;i++) stack[i]=NULL;/*初始化栈*/
q=p;
while(q!=NULL){
j++;
if(q->rchild!=NULL) stack[top++]=q->rchild;
if(q->lchild!=NULL) q=q->lchild;
else
if(top>0) q=stack[--top];
else q=NULL;
}
return j;
}
运行结果:

3、在上题中补充求二叉树中求叶子结点总数算法(提示:可在某种遍历过程中统计遍历的叶子结点数),并在主函数中补充相应的调用验证正确性。
算法代码:
int LeafNodes(BiTree p){
int num1,num2;
if(p==NULL)
return 0;
else if(p->lchild==NULL&&p->rchild==NULL)
return 1;
else
{
num1=LeafNodes(p->lchild);
num2=LeafNodes(p->rchild);
return (num1+num2);
}
}
运行结果:

4、在上题中补充求二叉树深度算法,并在主函数中补充相应的调用验证正确性。
算法代码:
int BTNodeDepth(BiTree p){
int lchilddep,rchilddep;
if(p==NULL)
return 0;
else{
lchilddep=BTNodeDepth(p->lchild);
rchilddep=BTNodeDepth(p->rchild);
return(lchilddep>rchilddep)?(lchilddep+1):(rchilddep+1);
}
运行结果:

5、补充二叉树层次遍历算法。(提示:利用队列实现)
void levelOrder(BiTree T){
if(T==NULL) return;
InitQueue(Q);//初始化一个队列
EnQueue(Q,T);
while(QueueEmpty(s)!=NULL){
Dequeue(Q,T);
visit(T);
if(T->lchild!=NULL) Enqueue(Q,T->lchild);
if(T->rchild!=NULL) Enqueue(Q,T->rchild);
}
}
6、补充二叉树中序、后序非递归算法。
中序:
void NRPreOrder(BiTree t) //非递归先序遍历二叉树
{
BiTree stack[maxsize],p;
int top; //栈顶
if(bt==NULL) return; //树为空则返回
top=0;
p=bt;
while(!(p==NULL&&top==0)) //当根结点不为空且栈不为空时
{
while(p!=NULL) //先深入左子树
{
if(top<=maxsize-1)
{
stack[top]=p; //入栈
top++; //栈顶位置++
}
else //栈满时
{
printf("栈溢出");
return;
}
p=p->lchild; //深入当前根结点的左子树
}
if(top<=0)return;
else
{
top--; //栈顶--,
p=stack[top]; //弹出栈顶元素
printf("%2c",&p->data); //在此处用打印表示访问该结点
p=p->rchild; //指向右子树
}
}
后序:
void Nrpostorder(BiTree T)
{
stacktype stack[max];
BiTree p;
int top,sign;
if(T==NULL) return;
top=-1;
p=T;
while(!(p==NULL&&top==-1))
{
if(p!=NULL)
{
top++;
stack[top].link=p;
stack[top].flag=1;
p=p->lchild;
}
else
{
p=stack[top].link;
sign=stack[top].flag;
top--;
if(sign==1)
{
top++;
stack[top].link=p;
stack[top].flag=2;
p=p->rchild;
}
else
{
printf("%2c",p->data);
p=NULL;
}
}
}
}
四、实验小结
通过实验,了解了二叉树的基本特性,学习了二叉树的先序、中序、后序的递归遍历算法和非递归遍历算法,还学习了求二叉树的深度、叶子结点数和层序遍历等算法,更加深刻的理解了二叉树的基本特性。

浙公网安备 33010602011771号