#include <iostream>
#include <cstdio>
#include <stdio.h>
#include <string>
#include <queue>
#include <stack>
using namespace std;
class Node{
public :
char data;
struct Node *lchild,*rchild;
};
class BiTree{
public:
Node * root;//头结点
int height=0;//树的高度
BiTree() {root=NULL;}
//层序创建二叉树
void create_level(string &s)
{
int p=0;
root=new Node();
Node *t,*i,*j;
queue<Node*> qTree;//定义一个队列,存储节点
while(true)
{
if(p==s.size())break;
if(p==0)//当头结点未创建
{
t=new Node();
t->data=s[p];
qTree.push(t);//头结点进队
root=t;
p++;
}
else
{
t=qTree.front();//该节点出队
if(p==s.size())break;//树的构建完毕
if(s[p]=='#')//不存在左节点
{
t->lchild=NULL;
p++;
}
else//存在左节点
{
i=new Node();
i->data=s[p];
t->lchild=i;//左节点进队
qTree.push(i);
p++;
}
if(p==s.size())break;
if(s[p]=='#')//不存在右节点
{
t->rchild=NULL;
p++;
}
else//存在右节点
{
j=new Node();
j->data=s[p];
t->rchild=j;
qTree.push(j);
p++;
}
qTree.pop();//节点左右节点已创建,该节点出队
}
}
}
//前序递归创建二叉树
void create_pre(string s)
{
int p=-1;
root=create(s,p);
}
Node *create(string &s,int &p)
{
++p;
Node *t;
if((unsigned)p>=s.size())
{
return NULL;
}
else
{
if(s[p]=='#')
{
t=NULL;
}
else
{
t=new Node;
t->data=s[p];
t->lchild=create(s,p);
t->rchild=create(s,p);
}
return t;
}
}
//前序递归遍历二叉树
void read_pre_oder(Node *t)
{
if(t!=NULL)
{
cout<<t->data<<' ';
read_pre_oder(t->lchild);
read_pre_oder(t->rchild);
}
}
//中序递归遍历二叉树
void read_mid_oder(Node *t)
{
if(t!=NULL)
{
read_mid_oder(t->lchild);
cout<<t->data<<' ';
read_mid_oder(t->rchild);
}
}
//后续递归遍历二叉树
void read_beh_oder(Node *t)
{
if(t!=NULL)
{
read_beh_oder(t->lchild);
read_beh_oder(t->rchild);
cout<<t->data<<' ';
}
}
//利用栈实现前序遍历二叉树
void read_pre_oder_stack(Node *t)
{
if(t!=NULL)
{
stack<Node*> sTree;//声明一个栈存储节点
while(true)
{
if(sTree.size()==0&&t==NULL) break;
while(true)//一直遍历左节点,输出
{
if(t==NULL) break;//该节点不存在左节点,跳出循环
cout<<t->data<<' ';
sTree.push(t);//节点进栈,以便后期遍历右节点
t=t->lchild;
}
t=sTree.top();//查看该节点是否存在右子树
sTree.pop();//节点已遍历出栈
/*遍历该节点右子树,若不存在右子树,继续循环,
存在则进入内部while循环查找该右子树的左节点*/
t=t->rchild;
}
}
}
//利用栈实现中序遍历二叉树
void read_mid_oder_stack(Node *t)
{
if(t!=NULL)
{
stack<Node*> sTree;//声明一个栈存储节点
while(true)
{
if(sTree.size()==0&&t==NULL) break;
while(true)
{
if(t==NULL) break;
sTree.push(t);//一直存储左节点
t=t->lchild;
}
t=sTree.top();
cout<<t->data<<' ';//不存在左节点,输出该节点
sTree.pop();//该节点出栈
t=t->rchild;//查找该节点的右子树
}
}
}
//利用栈实现后序遍历二叉树
void read_beh_oder_stack(Node *t)
{
if(t!=NULL)
{
stack<Node*> sTree1;//该栈用于存储遍历过程的节点
stack<Node*> sTree2;//该栈用于存储遍历结果,输出
sTree1.push(t);//头节点进栈
while(true)
{
if (sTree1.size()==0) break;
t=sTree1.top();
sTree1.pop();
if(t->lchild!=NULL)//存在左节点,节点进栈
{
sTree1.push(t->lchild);
}
if(t->rchild!=NULL)//存在右节点,节点进栈
{
sTree1.push(t->rchild);
}
sTree2.push(t);//存储该节点(第一步开始存储的就是头节点,头结点存储在栈底)
}
while(true)//输出
{
if(sTree2.size()==0) break;
t=sTree2.top();
cout<<t->data<<' ';
sTree2.pop();
}
}
}
//利用栈、队列实现层序遍历
void read_lev_oder_stack(Node *t)
{
if(t!=NULL)
{
stack<Node*> sTree;
queue<Node*> qTree;
sTree.push(t);
qTree.push(t);
while(true)
{
if(sTree.size()==0)break;
t=sTree.top();
sTree.pop();
if(t->lchild!=NULL)
{
sTree.push(t->lchild);
qTree.push(t->lchild);
}
if(t->rchild!=NULL)
{
sTree.push(t->rchild);
qTree.push(t->rchild);
}
}
while(true)
{
if(qTree.size()==0) break;
t=qTree.front();
cout<<t->data<<' ';
qTree.pop();
}
}
}
//求树的高度
int tree_height(Node *t)
{
get_height(t,0);
return height;
}
void get_height(Node *t,int h)
{
if(t==NULL) return;
h++;
if(h>height)
{
height=h;
}
get_height(t->lchild,h);
get_height(t->rchild,h);
}
};
int main()
{
BiTree a;
string s;
s="ABD##E#F##C##";
// a.create_level(s);
a.create_pre(s);
cout<<"递归实现前序遍历"<<endl;
a.read_pre_oder(a.root);
cout<<endl<<"递归实现中序遍历"<<endl;
a.read_mid_oder(a.root);
cout<<endl<<"递归实现后序遍历"<<endl;
a.read_beh_oder(a.root);
cout<<endl;
cout<<"栈实现前序遍历"<<endl;
a.read_pre_oder_stack(a.root);
cout<<endl<<"栈实现中序遍历"<<endl;
a.read_mid_oder_stack(a.root);
cout<<endl<<"栈实现后序遍历"<<endl;
a.read_beh_oder_stack(a.root);
cout<<endl<<"栈、队列实现层序遍历"<<endl;
a.read_lev_oder_stack(a.root);
cout<<endl<<"树的高度为: "<<endl;
int height=a.tree_height(a.root);
cout<<height<<endl;
return 0;
}
参考地址:https://blog.csdn.net/ajay666/article/details/76736333、https://www.cnblogs.com/ybf-yyj/p/8717601.html