实验8、二叉树的应用(简单易懂,注释超级全,代码可以直接运行)

实验8、二叉树的应用(简单易懂,注释超级全,代码可以直接运行)

(1)实验目的
通过该实验,使学生理解二叉树的链式存储,掌握二叉树的几种遍历算法,并通过该实验使学生理解递归的含义,掌握C语言编写递归函数的方法和注意事项。
(2)实验内容
实现教材中算法6.4描述的二叉树创建算法,在此基础上实现二叉树的先序、后序递归遍历算法、两种非递归中序遍历、层序遍历、求二叉树的深度。
(3)参考界面
在这里插入图片描述
(4)验收/测试用例
 创建

输入 :ABC$$DE$G$$F$$$       ($表示空格)

该输入对应的树如图所示
 先序 屏幕输出 A B C D E G F
 后序 屏幕输出 C G E F D B A
 中序 屏幕输出 C B E G D F A
(两种中序非递归还需看源代码)
 层序 屏幕输出 A B C D E F G
 深度 屏幕显示 深度为5
在这里插入图片描述
这个实验我当时写了一周左右,第一开始着手这个实验的时候,感觉手足无措,不知道怎么下手,在网上找了一篇程序后在不断的调整debug之后(网上有很多代码都是有bug的运行不起来😔)终于运行成功,于是拿着请教老师,老师并没有多看那个代码,给了我另一种解题思路,利用栈和队列结合起来来解决属的问题,先序和后序利用的是递归函数,很基本的操作,中序和层序遍历分别用的栈和队列来实现的,真的非常好,我晚上回去思考后一晚上就写出来了
我是当时老师带的所有学生中第一个写出来这个实验并通过的学生,有点装13了,给自己鼓个掌,🤭
在这里插入图片描述
话不多说,直接上代码吧(第一次写出来的程序就不贴上去的)

#include<stdio.h>
#include<stdlib.h>
#include<iostream>

using namespace std;

#define error 0
#define overflow -2
#define false -3
#define ok 1
#define maxsize 100 //栈和队列的最大存储空间 
typedef char TElemType;
//树的结构体
typedef struct BiTNode{
	TElemType data;
	struct BiTNode *lchild;
	struct BiTNode *rchild;
}BiTNode,*BiTree; 

typedef BiTree SElemType;
typedef BiTree QElemType;
//typedef char TElemType;
typedef int Status;
//栈结构体 
typedef struct{
	SElemType *top;
	SElemType *base;
	int stacksize;//栈可以用的最大容量 
}SqStack;
//队列结构体 
typedef struct QNode{
	QElemType data;
	struct QNode *next;
}QNode,*QueuePtr;

typedef struct{
	QueuePtr front;
	QueuePtr rear;
}LinkQueue;
//树的结构体
/*typedef struct BiTNode{
	TElemType data;
	struct BiTNode *lchild;
	struct BiTNode *rchild;
}BiTNode,*BiTree; */ 

//栈的函数
//初始化栈
Status InitStack(SqStack &S)
{
	S.base = (SElemType *)malloc(maxsize * sizeof(SElemType));//为栈申请空间 
	if(S.base == 0)
	{
		exit(overflow);
	}
	S.top = S.base;
	S.stacksize = maxsize;
	return ok;
}
//入栈函数
Status Push(SqStack &S,BiTree p)
{
	if(S.base == 0)
	{
		return error;//栈未初始化!! 
	}
	if(S.top - S.base == S.stacksize)
	{
		return false;
	}
	*S.top = p;//将地址入栈中 
	S.top++;//top指针上移 
	return ok;
} 
//出栈函数
Status Pop(SqStack &S,BiTree &p)
{
	if(S.base == 0)
	{
		return error;
	}
	if(S.base == S.top)
	{
		return false;
	}
	S.top--;
	p = *S.top;
	return ok;
} 
//获取栈顶元素
Status TopElem(SqStack S,BiTree &p)
{
	if(S.base == 0)
	{
		return error;
	}
	if(S.base == S.top)
	{
		return false;
	}
	S.top--;
	p = *S.top;
	return ok;
} 
//队列函数
//初始化队列
Status InitQueue(LinkQueue &Q)
{
	Q.front = (QueuePtr)malloc(sizeof(QNode));
	if(Q.front == 0)
	{
		exit(overflow);
	}
	Q.rear = Q.front;
	Q.front->next = 0;
	return ok;
} 
//入队
Status InserElem(LinkQueue &Q,BiTree p)
{
	if(Q.front == 0)
	{
		return error;
	}
	QueuePtr q;
	q = (QueuePtr)malloc(sizeof(QNode));
	q->data = p;
	q->next = 0;
	Q.rear->next = q;
	Q.rear = q;
	return ok;
 } 
 //出队
 Status DelElem(LinkQueue &Q,BiTree &p)
 {
 	if(Q.front == 0)
	{
		return error;
	}
	if(Q.front == Q.rear)
	{
		return false;
	}
	QueuePtr q;
	q = Q.front->next;//指向首元结点 
	p = q->data;
	Q.front->next = q->next;
	if(q == Q.rear)//保留尾指针,防止尾指针丢失 
	{
		Q.rear = Q.front;
	}
	free(q);
	return ok;
 }
 //树函数
 //先序创建树
Status CreatTree(BiTree &T)
{
	char ch;
	cout<<"请输入树中的元素:"<<endl;
	cin>>ch;
	if(ch == '$')
	{
		T = 0;
	}
	else{
		T = (BiTree)malloc(sizeof(BiTNode));
		if(T == 0)
		{
			exit(overflow);
		}
	    T->data = ch;//为结点赋值 
	    CreatTree(T->lchild);//构建左子树 
	    CreatTree(T->rchild);//构建右子树 
	}
	return ok;
} 
//先序遍历
Status PreOrderTraverse(BiTree T)
{
	if(T == 0)
	{
		return error;//空二叉树也是递归出口 
	}
	cout<<T->data<<" ";
	PreOrderTraverse(T->lchild);
	PreOrderTraverse(T->rchild);
} 
//后序遍历
 Status PostOrderTraverse(BiTree T)
{
	if(T == 0)
	{
		return error;//空二叉树也是递归出口 
	}
	PostOrderTraverse(T->lchild);
	PostOrderTraverse(T->rchild);
	cout<<T->data<<" ";
} 
//中序遍历1 
Status InOrderTraverse(BiTree T)
{
	if(T == 0)
	{
		return error;//空二叉树 
	}
	SqStack S;
	InitStack(S);
	while((T != 0)||(S.base != S.top))
	{
		
	    if(T != 0)
	    {
	    	Push(S,T);
	    	T = T->lchild;
		}
		else{
			Pop(S,T);
			cout<<T->data<<" ";
			T = T->rchild;
		}
	}
	return ok;
} 
//中序遍历2
Status InOrder_Traverse(BiTree T)
{
	if(T == 0)
	{
		return error;//空二叉树 
	}
	SqStack S;
	InitStack(S);
	Push(S,T);
	while(S.base != S.top)
	{
	while((TopElem(S,T) == ok)&&(T != 0))
	{
		Push(S,T->lchild);
	}
	Pop(S,T);
	if(S.base != S.top)
	{
		Pop(S,T);
		cout<<T->data<<" ";
		Push(S,T->rchild);
	}
    } 
    return ok;
}
//二叉树深度
Status DepthTree(BiTree T)
{
	if(T == 0)
	{
		return 0;//空二叉树也是递归出口 
	}
	int m,n;
	m = DepthTree(T->lchild);
	n = DepthTree(T->rchild);
	if(m > n)
	{
		return m + 1;
	}
	else{
		return n + 1;
	}
} 
//层序遍历
Status LevelOrderTraverse(BiTree T)
{
	if(T == 0)
	{
		return 0;//空二叉树也是递归出口 
	}
	LinkQueue Q;
	InitQueue(Q);
	InserElem(Q,T);
	while(Q.front != Q.rear)
	{
		DelElem(Q,T);
		cout<<T->data<<" ";
		if(T->lchild != 0)
		{
			InserElem(Q,T->lchild);
		}
		if(T->rchild != 0)
		{
			InserElem(Q,T->rchild);
		}
	}
	return ok;
} 
//主函数
int main()
{
	SqStack S;
	S.base = 0;
	LinkQueue Q;
	Q.front = 0;
	BiTree T;
	T = 0;
	int n,m,i,j;
	cout<<"*********************"<<endl;
	cout<<"1 9 2 5 0 5 0 3 4 3"<<endl;
	cout<<"1.创建二叉树"<<endl;
	cout<<"2.前序遍历二叉树"<<endl;
	cout<<"3.中序遍历二叉树1"<<endl;
	cout<<"4.中序遍历二叉树2"<<endl;
	cout<<"5.后序遍历二叉树"<<endl;
	cout<<"6.层序遍历二叉树"<<endl;
	cout<<"7.求二叉树深度"<<endl;
	cout<<"输入一个负数退出菜单!"<<endl;
	cout<<"*********************"<<endl;
	do{
		cout<<"请输入你的选择:"<<endl;
		cin>>n;
		switch(n)
		{
			case 1:
				CreatTree(T);
				cout<<endl;
				break;
			case 2:
				PreOrderTraverse(T);
				cout<<endl;
				break;
			case 3:
				InOrderTraverse(T);
				cout<<endl;
				break;
			case 4:
				InOrder_Traverse(T);
				cout<<endl;
				break;
			case 5:
				PostOrderTraverse(T);
				cout<<endl;
				break;
			case 6:
				LevelOrderTraverse(T);
				cout<<endl;
				break;
			case 7:
				m = DepthTree(T);
				cout<<"该二叉树的深度为:"<<m<<endl;
				break;
			default :
			    cout<<"请输入1~6的数!"<<endl;
				break;	
		}
	}while(n > 0);
} 

下面又到了手把手展示数据的环节辣
在这里插入图片描述
在这里插入图片描述
这个实验弄清楚原理就会非常简单嗷,赠人玫瑰,手留余香,👍也是这样嗷
在这里插入图片描述

  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

henu-于笨笨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值