#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