实验项目五:二叉树基本操作的实现

课程名称:数据结构
实验项目名称:二叉树基本操作的实现
实验目的:
1.掌握树的基本操作—遍历。
实验要求:
1、 分别用递归和非递归的方法实现一棵树的三种遍历。
实验过程:
1、 创建一棵二叉树(二叉树如下图所示);
2、 用递归算法实现对该树的三种遍历;
3、 用非递归算法实现对该树的三种遍历;
4、 输入选项:0或1,0为递归遍历,1为非递归遍历。
5、 根据输入的选项,分别调用递归或非递归算法输出先序、中序、后序遍历序列。
实验报告中给出先序和后序遍历的非递归实现算法代码。
实验结果:
1、输入:ABD##E##CF#G###(创建二叉树)
2、输入:0(递归算法)
3、输出: 先序遍历:ABDECFG
中序遍历:DBEAFGC
后序遍历:DEBGFCA
4、输入:1(非递归实现)
5、输出: 先序遍历:ABDECFG
中序遍历:DBEAFGC
后序遍历:DEBGFCA
实验分析:
1.分析递归与非递归实现的相同点及不同点;
2.列举调试运行过程中出现的错误并分析原因。
要求:
(1) 程序要添加适当的注释,程序的书写要采用缩进格式。
(2) 程序要具在一定的健壮性,即当输入数据非法时,程序也能适当地做出反应。
(3) 程序要做到界面友好,在程序运行时用户可以根据相应的提示信息进行操作。
(4) 上传源程序到课堂派。顺序表的源程序保存为TraversalBTree.cpp。

这篇博客并没有对算法进行讲解,只有实现代码,算法讲解可以去MOOC上看下西安邮电大学的数据结构课程,根据题目的输入和输出,二叉树的创建必须用前序

贴下代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>

using namespace std;

#define pi acos(-1.0)
#define e exp(1.0)
#define pa pair<char,ll>
typedef long long ll;
const ll maxn=1e5+7;
ll B;
struct node
{
	char data;
	node *lch;
	node *rch;
};
struct treenode//后序非递归遍历用的着 
{
	node *pos;
	bool vis;//标记节点的左右子树是否已经被访问完了 
};
void Create(node *&root)//前序创建二叉树,注意指针是引用 
{
	char c;
	c=getchar();
	if(c=='\n')
	return ;
	if(c=='#')
	root=NULL;
	else
	{
		root=new node;
		root->data=c;
		Create(root->lch);
		Create(root->rch);
	}
}
void PreOrder(node *now)//前序递归 
{
	if(now!=NULL)
	{
		printf("%c",now->data);
		PreOrder(now->lch);
		PreOrder(now->rch);
	}
	return ;
}
void InOrder(node *now)//中序递归 
{
	if(now!=NULL)
	{
		InOrder(now->lch);
		printf("%c",now->data);
		InOrder(now->rch);
	}
	return ;
}
void PostOrder(node *now)//后序递归 
{
	if(now!=NULL)
	{
		PostOrder(now->lch);
		PostOrder(now->rch);
		printf("%c",now->data);
	}
	return ;
}
void PreStack(node *now)//非递归前序 
{
	stack<node>sta;
	while(now!=NULL||!sta.empty())
	{
		if(now!=NULL)//
		{
			printf("%c",now->data);
			sta.push(*now);
			now=now->lch;
		}
		else//空节点 
		{
			if(!sta.empty())
			{
				now=sta.top().rch;
				sta.pop();
			}
			else//节点为空并且栈也为空,就退出,这个必须有 
			break;
		}
	}
	return ;
}
void InStack(node *now)//中序非递归遍历 
{
	stack<node>sta;
	while(now!=NULL||!sta.empty())
	{
		if(now!=NULL)//非空 
		{
			sta.push(*now);
			now=now->lch;
		}
		else//空节点 
		{
			if(!sta.empty())
			{
				printf("%c",sta.top().data);
				now=sta.top().rch;
				sta.pop();
			}
			else
			break;
		}
	}
	return ;
}
void PostStack(node *now)//后序非递归遍历 
{
	stack<treenode>sta;//此时栈的类型和前序中序不一样了 
	while(now!=NULL||!sta.empty())
	{
		while(now!=NULL)
		{
			treenode tn;
			tn.pos=now;
			tn.vis=0;
			sta.push(tn);
			now=now->lch;
		}
		while(!sta.empty()&&sta.top().vis==1)
		{
			printf("%c",sta.top().pos->data);
			sta.pop();
		}
		if(!sta.empty())
		{
			sta.top().vis=1;
			now=sta.top().pos->rch;
		}
	}
	return ;
}
void Delete(node *root)//清空内存,这个也是必须的 ,后序清空 
{
	if(root!=NULL)
	{
		Delete(root->lch);
		Delete(root->rch);
		delete root;
	}
	return ;
}
int main()
{
// freopen(".../.txt","w",stdout);
// ios::sync_with_stdio(false);
	ll i,j;
	node *root=NULL;
	Create(root);
	scanf("%lld",&B);
	if(!B)//递归遍历 
	{
		 PreOrder(root);//前序遍历 
		 putchar('\n');
		 InOrder(root);//中序遍历 
		 putchar('\n');
		 PostOrder(root);//后序遍历 
		 putchar('\n');
	}	
	else//非递归遍历 
	{
		PreStack(root);
		putchar('\n');
		InStack(root);
		putchar('\n');
		PostStack(root);
		putchar('\n'); 
	}
	Delete(root);
	return 0;
}