第六次作业:二叉树
| 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/qdu/DS2020 |
|---|---|
| 这个作业要求在哪里 | https://edu.cnblogs.com/campus/qdu/DS2020/homework/11392 |
| 这个作业的目标 | 二叉树的特点,二叉树的历遍算法、深度算法 |
| 学号 | 2018204261 |
实验四:二叉树
一、实验目的
1、掌握二叉树的基本特性
2、掌握二叉树的先序、中序、后序的递归遍历算法
3、理解二叉树的先序、中序、后序的非递归遍历算法
4、通过求二叉树的深度、叶子结点数和层序遍历等算法,理解二叉树的基本特性
二、实验预习
说明以下概念
1、二叉树:二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根(root)的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个结点。
2、递归遍历:二叉树本身的定义是递归的,我们在设计遍历算法时可以利用二叉树的这一特性,在遍历函数中调用函数本身。
3、非递归遍历:不采用递归·的方法实现遍历函数。
4、层序遍历:从二叉树的第一层(根节点)开始,从上至下逐层遍历,在同一层中,则按照从左到右的顺序对节点逐个访问。在逐层遍历过程中,按从顶层到底层的次序访问树中元素,在同一层中,从左到右进行访问。
三、实验内容和要求
1、阅读并运行下面程序,根据输入写出运行结果,并画出二叉树的形态。
#include<stdio.h>
#include<malloc.h>
#include<iostream>
#include<conio.h>
#define MAX 20
typedef struct BTNode{ /*节点结构声明*/
char date; /*节点数据*/
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->date=s;
*t=q;
createBiTree(&q->lchild); /*递归建立左子树*/
createBiTree(&q->rchild); /*递归建立右子树*/
}
int PreOrder(BiTree p){ /*先序遍历二叉树*/
if(p!=NULL)
{
printf("%c",p->date);
PreOrder(p->lchild);
PreOrder(p->rchild);
}
}
void InOrder(BiTree p){ /*中序遍历二叉树*/
if(p!=NULL)
{
InOrder(p->lchild);
printf("%c",p->date);
InOrder(p->rchild);
}
}
void PostOrder(BiTree p){ /*后序遍历二叉树*/
if(p!=NULL)
{
PostOrder(p->lchild);
PostOrder(p->rchild);
printf("%c",p->date);
}
}
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->date);
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);
printf("\n\n总结点数");
printf("%d",PreOrder_num(t));
printf("\n\n叶总结点数:");
printf("%d",LeafNodes(t));
printf("\n\n树的深度:");
printf("%d",BTNodeDepth(t));
release(t);
return 0;
}
·运行程序
输入:
ABC##DE#G##F###

2、在上题中补充求二叉树中求结点总数算法(提示:可在某种遍历过程中统计遍历的结点数),并在主函数中补充相应的调用验证正确性。
算法代码:
#include<stdio.h>
#include<malloc.h>
#include<iostream>
#include<conio.h>
#define MAX 20
typedef struct BTNode{ /*节点结构声明*/
char date; /*节点数据*/
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->date=s;
*t=q;
createBiTree(&q->lchild); /*递归建立左子树*/
createBiTree(&q->rchild); /*递归建立右子树*/
}
int PreOrder(BiTree p){ /*先序遍历二叉树*/
if(p!=NULL)
{
printf("%c",p->date);
PreOrder(p->lchild);
PreOrder(p->rchild);
}
}
void InOrder(BiTree p){ /*中序遍历二叉树*/
if(p!=NULL)
{
InOrder(p->lchild);
printf("%c",p->date);
InOrder(p->rchild);
}
}
void PostOrder(BiTree p){ /*后序遍历二叉树*/
if(p!=NULL)
{
PostOrder(p->lchild);
PostOrder(p->rchild);
printf("%c",p->date);
}
}
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->date);
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 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;
}
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);
printf("\n\n总结点数");
printf("%d",PreOrder_num(t));
printf("\n\n叶总结点数:");
printf("%d",LeafNodes(t));
printf("\n\n树的深度:");
printf("%d",BTNodeDepth(t));
release(t);
return 0;
}

3、在上题中补充求二叉树中求叶子结点总数算法(提示:可在某种遍历过程中统计遍历的叶子结点数),并在主函数中补充相应的调用验证正确性。
算法代码:
int LeafNodes(BiTree p){
int num1=0,num2=0;
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);
}
}

四、总结
1、对于函数getche(),要引入头文件
#include<conio.h>
2、对于函数exit(),要引入头文件
#include<iostream>

浙公网安备 33010602011771号