#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
