数据结构实验 二叉树的实现

数据结构实验 二叉树的实现

实验内容
本人完成了二叉树基本操作的实现,包含二叉树的建立、复制、交换左右子树;判断两棵二叉树是否相同;求二叉树的深度、宽度、叶子结点数量;二叉树的先序、中序、后序遍历,分别用递归和非递归两种方式进行了实现,以及二叉树的层次遍历(广度优先遍历)。

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <stack>
#include <queue>
using namespace std;

typedef struct BitNode//二叉树 
{
	char data;
	BitNode *Lchild,*Rchild;
}BitNode,*BiTree;

void CreateBiTree(BiTree &T)//建立二叉树:按先序次序输入二叉树中结点的值(字符),“#”表示空树 
{
	char ch;
	cin>>ch;
	if(ch=='#') T=NULL;
	else
	{
		T=new BitNode;
		T->data=ch;
		CreateBiTree(T->Lchild);
		CreateBiTree(T->Rchild);
	}
}

void CopyBiTree(BiTree &S,BiTree T)//二叉树的复制 
{
	if(T==NULL)
	{
		S=NULL;
		return;
	}
	S=new BitNode;
	S->data=T->data;
	CopyBiTree(S->Lchild,T->Lchild);
	CopyBiTree(S->Rchild,T->Rchild);
}

void ChangeBiTree(BiTree T)//交换左右子树 
{
	if(T==NULL) return;
	BiTree temp=T->Lchild;
	T->Lchild=T->Rchild;
	T->Rchild=temp;
	ChangeBiTree(T->Lchild);
	ChangeBiTree(T->Rchild);
}

int IsSame(BiTree S,BiTree T)//判断两棵二叉树是否相同 
{
	if(S==NULL&&T==NULL)//两棵树都为空 
		return 1;
	if(S==NULL&&T!=NULL||S!=NULL&T==NULL)//一棵树为空一棵树不为空 
		return 0;
	if(S->data!=T->data)//结点的值不同 
		return 0;
	return IsSame(S->Lchild,T->Lchild)&&IsSame(S->Rchild,T->Rchild);//继续判断它们的左右子树是否相同 
}

int Depth(BiTree T)//求二叉树的深度 
{
	if(T==NULL) return 0;
	int l=Depth(T->Lchild);
	int r=Depth(T->Rchild);
	return l>r?l+1:r+1;
}

int Width(BiTree T)//求二叉树的宽度(每层结点数的最大值) 
{
	if(T==NULL) return 0;
	int maxn=1;//每层结点数的最大值 
	queue<BiTree> q;
	q.push(T);
	BiTree p=NULL;
	while(1)
	{
		int size=q.size();
		if(size==0) break;
		while(size>0)
		{
			p=q.front();
			q.pop();
			size--;
			if(p->Lchild)
				q.push(p->Lchild);
			if(p->Rchild)
				q.push(p->Rchild);
		}
		size=q.size();
		maxn=max(maxn,size);
	}
	return maxn;
}

int Leafcnt(BiTree T)//求叶子结点数量 
{
	if(T==NULL) return 0;
	int l=Leafcnt(T->Lchild);
	int r=Leafcnt(T->Rchild);
	if(T->Lchild==NULL&&T->Rchild==NULL)
		return l+r+1;
	return l+r; 
}

void PreOrderTraverse(BiTree T)//先序遍历(递归) 
{
	if(T==NULL) return;
	cout<<T->data;
	PreOrderTraverse(T->Lchild);
	PreOrderTraverse(T->Rchild);
}

void InOrderTraverse(BiTree T)//中序遍历(递归) 
{
	if(T==NULL) return;
	InOrderTraverse(T->Lchild);
	cout<<T->data;
	InOrderTraverse(T->Rchild);
}

void PostOrderTraverse(BiTree T)//后序遍历(递归) 
{
	if(T==NULL) return;
	PostOrderTraverse(T->Lchild);
	PostOrderTraverse(T->Rchild);
	cout<<T->data;
}

void PreOrderTraverse_(BiTree T)//先序遍历(非递归) 
{
	if(T==NULL) return;
	stack<BiTree> s;
	BiTree p=NULL;
	s.push(T);
	while(!s.empty())
	{
		p=s.top();
		s.pop();
		cout<<p->data;//出栈结点并访问 
		if(p->Rchild)
			s.push(p->Rchild);//访问左子树 
		if(p->Lchild)
			s.push(p->Lchild);//访问右子树 
	}
}

void InOrderTraverse_(BiTree T)//中序遍历(非递归) 
{
	if(T==NULL) return;
	stack<BiTree> s;
	BiTree p=T;
	while(p!=NULL||!s.empty())
	{
		if(p!=NULL)
		{
			s.push(p);
			p=p->Lchild;//访问左子树 
		}
		else
		{
			p=s.top();
			s.pop();
			cout<<p->data;
			p=p->Rchild;//访问右子树 
		}
	}
}

void PostOrderTraverse_(BiTree T)//后序遍历(非递归) 
{
	if(T==NULL) return;
	stack<BiTree> s;
	BiTree pre=NULL,cur=NULL;
	s.push(T);//根节点入栈 
	while(!s.empty())
	{
		cur=s.top();
		if((cur->Lchild==NULL&&cur->Rchild==NULL)//不存在左右子树 
		  ||pre!=NULL&&(pre==cur->Lchild||pre==cur->Rchild))//或左右子树都已访问过 
		{
			s.pop();
			cout<<cur->data;
			pre=cur;
		}
		else
		{
			if(cur->Rchild!=NULL)
				s.push(cur->Rchild);//右子树入栈 
			if(cur->Lchild!=NULL)
				s.push(cur->Lchild);//左子树入栈 
		}
	}
}

void LevelOrderTraverse(BiTree T)//层次遍历(广度优先遍历) 
{
	if(T==NULL) return;
	queue<BiTree> q;
	q.push(T);
	BiTree p=NULL;
	while(!q.empty())
	{
		p=q.front();
		q.pop();
		cout<<p->data;
		if(p->Lchild)
			q.push(p->Lchild);
		if(p->Rchild)
			q.push(p->Rchild);
	}
}


int main()
{
	BiTree T;//二叉树根节点 
	cout<<"请按照序次序输入二叉树,空结点用#表示:"<<endl; 
	CreateBiTree(T);//建立二叉树:按先序次序输入二叉树中结点的值(字符),“#”表示空树 
	cout<<"二叉树的先序遍历:"<<endl;
	cout<<"递归实现:  ";
	PreOrderTraverse(T);
	cout<<endl;
	cout<<"非递归实现:";
	PreOrderTraverse_(T);
	cout<<endl;
	cout<<"二叉树的中序遍历:"<<endl;
	cout<<"递归实现:  ";
	InOrderTraverse(T);
	cout<<endl;
	cout<<"非递归实现:";
	InOrderTraverse_(T);
	cout<<endl;
	cout<<"二叉树的后序遍历:"<<endl;
	cout<<"递归实现:  ";
	PostOrderTraverse(T);
	cout<<endl;
	cout<<"非递归实现:";
	PostOrderTraverse_(T);
	cout<<endl;
	cout<<"二叉树的层次遍历:";
	LevelOrderTraverse(T);
	cout<<endl;
	cout<<"二叉树T的深度为:";
	cout<<Depth(T)<<endl;
	cout<<"二叉树T的宽度为:";
	cout<<Width(T)<<endl;
	cout<<"二叉树T的叶子结点数量为:";
	cout<<Leafcnt(T)<<endl; 
	cout<<"将二叉树T复制到新二叉树S"<<endl;
	cout<<"新二叉树S的层次遍历:";
	BiTree S;
	CopyBiTree(S,T);
	LevelOrderTraverse(S);
	cout<<endl;
	cout<<"二叉树T和S是否相同:";
	cout<<IsSame(T,S)<<endl;
	cout<<"交换二叉树T的左右子树"<<endl;
	ChangeBiTree(T);
	cout<<"交换左右子树后的层次遍历:";
	LevelOrderTraverse(T);
	cout<<endl;
	cout<<"二叉树T和S是否相同:";
	cout<<IsSame(T,S)<<endl;
	return 0;
}
/*
	测试数据:
	1  ABDF##G##E##C##
	2  ABC##DE#G##F###
	3  ABD##E##C#F##
*/

测试样例
在这里插入图片描述
测试结果截图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

问题解决和心得记录
这是我的第六次数据结构课程实验,我完成了二叉树基本操作的实现。之前在ACM的训练有接触过一些二叉树的题目,但并没有用到特别多的操作。在此次实验中我用自己的代码对二叉树的一些基本操作进行了实现,相比学习书本上的内容和做习题,让我对二叉树这一数据类型有了更深入的认识和理解。

编写代码的过程中也曾出现过一些小的失误,我通过查阅资料得知了问题所在。比如指针的使用等需要更加细心一些,否则就可能造成错误。经过我的耐心修改和调试以后,最终都能够运行得到正确的结果。

编程能力的提升是一个日积月累的过程。有时候可能为了搞懂一些内容,而不仅仅是蒙混过关,确实自己在课外要花非常多的时间。我一直相信,这些付出最终都会有回报。数据结构是非常重要的专业核心课程,要感谢老师用心的指导。我将在后续的学习中再接再厉,争取在期末考试中取得理想的成绩,也为将来的课程学习打下扎实的基础。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

球王武磊

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

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

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

打赏作者

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

抵扣说明:

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

余额充值