二叉树先序中序后续层次遍历的不同实现方法

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<unordered_set>
#define MAXLENGTH 100
using namespace std;

template<typename T>
struct node{				//树结点结构体 
	T val;
	struct node *lchild;
	struct node *rchild;
	
};
template<typename T>
struct quenode{				//队列结点结构体 
	T val;
	struct quenode * next;
};
template<typename T>
class stack{				//自己实现的模板类栈 
	private:
		T * base,* toppo;
		int nowlen;
	public:
		
		stack()				//栈的构造函数,生成一个栈 
		{
			base=(T *)malloc(sizeof(T)*MAXLENGTH);//分配空间 
			if(!base)
			{
				cout<<"error";
				return;
			}
			nowlen=MAXLENGTH;
			toppo=base;
		}
		void push(T val)	//向栈中压入一个元素 
		{
			if(toppo-base==99) base=(T *)realloc(base,sizeof(T)*(nowlen+(int)MAXLENGTH));
			
			toppo++;
			*toppo=val;
		}
		~stack()
		{
			free(base);
		}
		T top()			//获取栈顶端元素 
		{
			if(base==toppo)
			{
				cout<<"error";
				return *base;
			}
			return *toppo;
		}
		bool empty()	//判断栈是否为空 
		{
			if(base==toppo) return true;
			else return false;
		}
		void pop()		//弹出栈顶端元素 
		{
			if(base==toppo)
			{
				cout<<"error";
				return ;
			}
			toppo--;
		}

}; 
template<typename T>
class queue{			//自己实现的模板类队列 
	public:
		
		bool empty()	//判断队列是否为空 
		{
			if(frontpo==tailpo) return true;
			else return false;
		}
		queue()			//队列的构造函数,生成一个队列 
		{
			frontpo =new(struct quenode <T>);
			if(frontpo==0)
			{
				cout<<"error";
				return ;
			}
			frontpo->next=nullptr;
			tailpo=frontpo;
			
		}
		~queue()//析构函数 
		{
			struct quenode <T> *now=frontpo,*temp=frontpo->next;
			while(temp!=nullptr)
			{
				delete(now);
				now=temp;
				temp=now->next;
			}
		} 
		void insert(T val)	//向队列尾部插入一个元素 
		{
			struct quenode<T> * newnode=new(struct quenode<T>);
			if(newnode==nullptr)
			{
				cout<<"error";
				return ;
			}
			newnode->val=val;
			newnode->next=nullptr;
			struct quenode<T> * temp = tailpo->next;
			tailpo->next=newnode;
			newnode->next=temp;
			tailpo=newnode;
			return ;
		}
		T front()		//获取队首元素 
		{
			return frontpo->next->val;
		}
		void pop()		//将队首元素出队 
		{
			if(frontpo==tailpo)
			{
				cout<<"error";
				return ;
			}
			struct quenode <T> *temp = frontpo->next;
			
			frontpo->next=temp->next;
			if(temp==tailpo) tailpo=frontpo;
			delete(temp);
			
		}
	private:
		struct quenode<T> * frontpo,*tailpo;
		
};
template<typename T>
class tree{		//实现的模板树 
	public:
		struct node<T> * root;
		tree ()	//构造函数,生成一个树 
		{
			root=new(struct node<T>);
			if(root==nullptr)
			{
				cout<<"error";
				return ;
			}
			sum=1;
			root->val=1;
			root->lchild=nullptr;//将左右结点指向空 
			root->rchild=nullptr;
		}
		~tree()//利用队列来实现析构 
		{
			int lastwide,wi;
			wi=1;
			queue<struct node <T> *> que;//利用一个队列来存储 
			que.insert(root);
			while(!que.empty())
			{
				lastwide=wi;//记录上一层结点个数 
				wi=0;
				for(int i=1;i<=lastwide;i++)//将上一层结点元素都从队列中弹出,并将这一层的结点全部加入队列 
				{
					struct node <T> * temp=que.front();
					que.pop();
				
					if(temp->lchild!=nullptr) {wi++;que.insert(temp->lchild);}
					if(temp->rchild!=nullptr) {wi++;que.insert(temp->rchild);}		
					delete(temp);//上一层的结点孩子结点全加入队列后,析构 
				}
			}
		}
		void preorder(struct node <T> *);//先序遍历 
		void midorder(struct node <T> *);//中序遍历 
		void lasorder(struct node <T> *);//后序遍历 
		void levelorder();//层次遍历 
		void preorder2();//先序遍历(非递归) 
		void midorder2();//中序遍历(非递归) 
		void lasorder2();//后续遍历(非递归) 
		void buildson(struct node  <T>*,T,T,bool,bool);//对一个父结点建立两个子节点 
		int sum;
		//void connect();

};

template<typename T>
void tree<T>::buildson(struct node<T> * fa,T val1,T val2,bool t1,bool t2)//对一个父结点建立两个子节点 
{
	fa->lchild=new(struct node<T>);//申明左孩子结点空间 
	fa->rchild=new(struct node<T>);//申明右孩子结点空间
	if(!fa->lchild)
	{
		cout<<"error";
		return ;
	}
	if(!fa->rchild)
	{
		cout<<"error";
		return ;
	}
	if(t1) //用-1来表示无该结点 
	{
		fa->lchild->val=val1;
		fa->lchild->lchild=fa->lchild->rchild=nullptr;
	}
	else 
		fa->lchild=nullptr;
	if(t2) 
	{
		fa->rchild->val=val2;
		fa->rchild->lchild=fa->rchild->rchild=nullptr;
	}
	else 
		fa->rchild=nullptr;
}

template<typename T>
void tree<T>::preorder(struct node <T> * nownode)//先序遍历 
{
	if(nownode==nullptr) return;
	cout<<nownode->val<<" ";//输出根结点 
	if(nownode->lchild) preorder(nownode->lchild);//遍历左子树 
	if(nownode->rchild) preorder(nownode->rchild);//遍历右子树 
	return ;
}
template<typename T>
void tree<T>::midorder(struct node <T> * nownode)
{
	if(nownode==nullptr) return;
	
	if(nownode->lchild!=nullptr) midorder(nownode->lchild);//遍历左子树
	cout<<nownode->val<<" ";//输出根结点 
	if(nownode->rchild!=nullptr) midorder(nownode->rchild);//遍历右子树 
	return ;
}
template<typename T>
void tree<T>::lasorder(struct node <T> * nownode)
{
	if(nownode==nullptr) return;
	
	if(nownode->lchild!=nullptr) lasorder(nownode->lchild);//遍历左子树
	if(nownode->rchild!=nullptr) lasorder(nownode->rchild);//遍历右子树 
	cout<<nownode->val<<" ";//输出根结点 
	return ;
}
template<typename T>
void tree<T>::levelorder()
{
	queue<struct node <T> *> que;//先声明一个队列 
	que.insert(root);//将根节点加入队列中 
	while(!que.empty())
	{
		struct node <T> * now=
		que.front();//获取队首元素 
		que.pop();
		cout<<now->val<<" ";//输出当前结点 
		if(now->lchild!=nullptr) que.insert(now->lchild);//如果左孩子存在则加入队列 
		if(now->rchild!=nullptr) que.insert(now->rchild);//如果右孩子存在则加入队列

	}
}

template<typename T>
void tree<T>::preorder2()//先序遍历非递归 
{
	queue<struct node<T> *> que;//声明一个队列 
	stack<struct node <T>*> sta;//声明一个栈
	que.insert(root);
	while(!(que.empty()&&sta.empty()))
	{
		if(!que.empty())//当栈不为空时 
		{
			struct node <T> * temp=que.front();//获取队首元素 
			que.pop();
			cout<<temp->val<<' ';//输出当前元素 
			if(temp->lchild) que.insert(temp->lchild);//如果左孩子存在,则将它加入队列 
			if(temp->rchild) sta.push(temp->rchild);//如果右孩子存在,则压入栈,因为右子树的元素月在后面压入越先访问 
		}
		else //如果队列为空,则要将栈顶元素加入到队列中 
		{
			struct node<T> * temp=sta.top();
			sta.pop();
			que.insert(temp);	
		}
	}
}
template<typename T>
void tree<T>::midorder2()//中序遍历非递归 
{
	stack<struct node <T>*> sta;//声明一个栈
	struct node <T> * temp=root;//将根节点压入栈中 
	while(temp)
	{
		sta.push(temp);
		temp=temp->lchild;//将结点所有的左节点压入栈中 
	}
	while(!sta.empty())
	{
		struct node <T> * now=sta.top();//获取栈顶元素 
		cout<<now->val<<" ";//输出元素 
		sta.pop();
		if(now->rchild)//如果存在右孩子,则开始访问右子树 
		{
			struct node <T> * nowr=now->rchild;//将右子树所有左孩子压入栈中 
			while(nowr)
			{
				sta.push(nowr);
				nowr=nowr->lchild;
			}
		}
	}	
} 
template<typename T>
void tree<T>::lasorder2()//后序遍历非递归 
{
	unordered_set<struct node <T> *> setw;//利用一个集合来判断是否已经被访问过 
	stack<struct node <T> *> sta;//声明一个栈 
	struct node <T> * temp=root;
	while(temp)
	{
		sta.push(temp);
		temp=temp->lchild;//将结点所有的左节点压入栈中 
	}
	while(!sta.empty())
	{
		struct node <T> * now=sta.top();//获取栈顶元素 
		
		if(now->rchild && setw.count(now)==0)//如果右孩子存在且没被访问过 则将它左孩子加入到栈中 
		{
			setw.insert(now);
			struct node <T> * nowr=now->rchild;
			while(nowr)
			{
				sta.push(nowr);
				nowr=nowr->lchild;
			}
		}
		else//输出它 
		{
			cout<<now->val<<" ";
			sta.pop();
		}
	}	
	
	
} 
int main(){
	tree<int> t1;//建树 
	t1.buildson(t1.root,2,3,1,1);
	t1.buildson(t1.root->lchild,4,5,1,1);
	t1.buildson(t1.root->rchild,-1,9,0,1);
	t1.buildson(t1.root->lchild->lchild,7,6,1,1);
	t1.buildson(t1.root->lchild->rchild,8,10,1,1);
	t1.buildson(t1.root->rchild->rchild,11,12,1,1);
	cout<<endl<<"先序遍历为:";
	t1.preorder(t1.root);
	cout<<endl<<"中序遍历为:";
	t1.midorder(t1.root);
	cout<<endl<<"后序遍历为:";
	t1.lasorder(t1.root);
	cout<<endl<<"层次遍历为:";
	t1.levelorder();
	cout<<endl<<"先序遍历(非递归)为:";;
	t1.preorder2();
	cout<<endl<<"中序遍历(非递归)为:";;
	t1.midorder2();
	cout<<endl<<"后序遍历(非递归)为:";;
	t1.lasorder2();
	return 0;
} 

 树的结构如上

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值