二叉树的遍历与应用

warning: 这篇文章距离上次修改已过234天,其中的内容可能已经有所变动。

很多与二叉树相关的算法都是二叉树遍历算法的扩展,所以要熟练掌握对二叉树的各种遍历算法,包括前中后序,层序的递归和非递归算法实现

#include<iostream>
#include<queue>
#include<stack>
#define ElemType char
#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;
}
none
最后修改于:2021年09月23日 19:27

添加新评论