很多与二叉树相关的算法都是二叉树遍历算法的扩展,所以要熟练掌握对二叉树的各种遍历算法,包括前中后序,层序的递归和非递归算法实现
#include<iostream>
#include<queue>
#include<stack>
#define ElemType int
#define MaxSize 50
using namespace std;
int widths[MaxSize];
typedef struct BiTNode{
ElemType data;
struct BiTNode*lchild,*rchild;
}BiTNode,*BiTree;
BiTree CreateBiTree()
{
ElemType x;
BiTree T;
cin>>x;
if(x==0)T=NULL;
else {
T=(BiTNode*)malloc(sizeof(BiTNode));
T->data=x;
T->lchild=CreateBiTree();
T->rchild=CreateBiTree();
}
return T;
}
void visit(BiTNode*node)
{
if(node)cout<<node->data<<" ";
}
//非递归
void PreOrder(BiTree T)
{
stack<BiTNode*>st;
BiTree p=T;
while(p||st.size()){
if(p){
st.push(p);
visit(p);
p=p->lchild;
}
else{
p=st.top(),st.pop();
p=p->rchild;
}
}
}
void InOrder(BiTree T)
{
stack<BiTNode*>st;
BiTree p=T;
while(p||st.size()){
if(p){
st.push(p);
p=p->lchild;
}
else{
p=st.top(),st.pop();
visit(p);
p=p->rchild;
}
}
}
void PostOrder(BiTree T)
{
stack<BiTNode*>st;
BiTree p=T;
BiTNode *r=nullptr;
while(p||st.size()){
if(p){
st.push(p);
p=p->lchild;
}
else{
p=st.top();
if(p->rchild&&p->rchild!=r)
p=p->rchild;
else{
st.pop();
visit(p);
r=p;
p=nullptr;
}
}
}
}
void LevelOrder(BiTree T)
{
queue<BiTNode*>q;
BiTree p=T;
q.push(p);
while(q.size()){
BiTNode*t=q.front();
q.pop();
visit(t);
if(t->lchild)q.push(t->lchild);
if(t->rchild)q.push(t->rchild);
}
}
//自下而上,从右到左
void InvertLevel(BiTree T)
{
stack<BiTNode*>st;
queue<BiTNode*>q;
BiTree p=T;
q.push(p);
while(q.size()){
BiTNode*t=q.front();
q.pop();
st.push(t);
if(t->lchild)q.push(t->lchild);
if(t->rchild)q.push(t->rchild);
}
while(st.size()){
BiTNode*r=st.top();
visit(r);
st.pop();
}
}
int GetHigh1(BiTree T)//非递归,基于先序遍历
{
BiTree p=T;
if(!p)return 0;
int h=0,res=0;
stack<BiTNode*>st;
while(p||st.size()){
if(p){
st.push(p);
h++;
res=h>res?h:res;
p=p->lchild;
}
else{
p=st.top();
st.pop();
h--;
p=p->rchild;
if(p)h++;
}
}
return res;
}
int GetHigh2(BiTree T)//基于层序遍历
{
if(!T)return 0;
BiTree Q[MaxSize];
BiTNode*p;
int front=-1,rear=-1;
int last=0,level=0;
Q[++rear]=T;
while(front<rear){
p=Q[++front];
if(p->lchild)Q[++rear]=p->lchild;
if(p->rchild)Q[++rear]=p->rchild;
if(front==last){
level++;
last=rear;
}
}
return level;
}
void GetWidth(BiTree T)//基于层序遍历
{
if(!T)return;
widths[0]=1;
BiTree Q[MaxSize];
BiTNode*p;
int front=-1,rear=-1;
int last=0,level=0;
Q[++rear]=T;
while(front<rear){
p=Q[++front];
if(p->lchild)Q[++rear]=p->lchild;
if(p->rchild)Q[++rear]=p->rchild;
if(front==last){
level++;
last=rear;
widths[level]=last-front;
}
}
}
//根据先序+中序建树
BiTree PreInCreate(ElemType A[],ElemType B[],int s1,int e1,int s2,int e2)
//s1,s2表示A,B的开始下标,e1,e2表示A,B的结束下标,A数组表示先序序列,B中序序列
{
BiTree root=(BiTree)malloc(sizeof(BiTNode));
root->data=A[s1];
int i=s2;
while(B[i]!=root->data)i++;
int len1=i-s2;//表示左子树的结点个数
int len2=e2-i;//表示右子树的结点个数
if(len1){
root->lchild=PreInCreate(A,B,s1+1,s1+len1,s2,s2+len1-1);
}else root->lchild=nullptr;
if(len2){
root->rchild=PreInCreate(A,B,e1-len2+1,e1,e2-len2+1,e2);
}else root->rchild=nullptr;
return root;
}
//根据后序+中序建树
BiTree PostInCreate(ElemType A[],ElemType B[],int s1,int e1,int s2,int e2)
//s1,s2表示A,B的开始下标,e1,e2表示A,B的结束下标,A数组表示后序序列,B中序序列
{
BiTree root=(BiTree)malloc(sizeof(BiTNode));
root->data=A[e1];
int i=s2;
while(B[i]!=root->data)i++;
int len1=i-s2;//表示左子树的结点个数
int len2=e2-i;//表示右子树的结点个数
if(len2){
root->rchild=PostInCreate(A,B,e1-len2,e1-1,e2-len2+1,e2);
}else root->rchild=nullptr;
if(len1){
root->lchild=PostInCreate(A,B,s1,s1+len1-1,s2,s2+len1-1);
}else root->lchild=nullptr;
return root;
}
//根据层序+中序建树
BiTree LevelInCreate(ElemType A[],ElemType B[],int s1,int e1,int s2,int e2)
//s1,s2表示A,B的开始下标,e1,e2表示A,B的结束下标,A数组表示层序序列,B中序序列
{
BiTree root=(BiTree)malloc(sizeof(BiTNode));
root->data=A[s1];
int i=s2;
while(B[i]!=root->data)i++;
int len1=i-s2;//表示左子树的结点个数
int len2=e2-i;//表示右子树的结点个数
return root;
}
int main()
{ //1 2 3 0 0 4 0 0 5 0 0
BiTree T; //5 3 2 0 0 0 8 6 0 0 9 0 0
/**
*
* 5
* / \
* 3 8
* / / \
* 2 6 9
*
*
**/
//T=CreateBiTree();
int A[10]={5,3,2,8,6,9},B[10]={2,3,5,6,8,9},C[10]={2,3,6,9,8,5};
//T=PreInCreate(A,B,0,5,0,5);
T=PostInCreate(C,B,0,5,0,5);
cout<<"pre:";//5 3 2 8 6 9
PreOrder(T);
cout<<"\nin:";//2 3 5 6 8 9
InOrder(T);
cout<<"\npost:";//2 3 6 9 8 5
PostOrder(T);
cout<<"\nlevel:";
LevelOrder(T);
cout<<"\n自下而上,从右到左遍历:";
InvertLevel(T);
cout<<"\nhigh:";
cout<<GetHigh1(T)<<" "<<GetHigh2(T);
cout<<"\nwidth each storey:";
GetWidth(T);
for(int i=0;i<GetHigh1(T);i++)cout<<widths[i]<<" ";
return 0;
}