第六次作业:二叉树

这个作业属于哪个课程 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>
posted @ 2020-11-06 12:25  山海志  阅读(320)  评论(0)    收藏  举报