#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;
}
树的结构如上