二叉树的非递归先序,中序,后序遍历

简介:

#include<iostream> 
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<stack>
using namespace std;

struct Tree{
    int x;
    Tree *lchild, *rchild;
    Tree(){
        lchild = rchild = NULL;
    }
};

typedef Tree* pT;

void buildT(pT &T){
    int n;
    cin>>n;
    if(n==-1)
        return;
    T = new Tree();
    T->x = n;
    buildT(T->lchild);
    buildT(T->rchild);
}
/**************************************************************************/ 
/*
     非递归先序遍历: 对于任一结点P:

     1)访问结点P,并将结点P入栈;

     2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,
    循环至1); 若不为空,则将P的左孩子置为当前的结点P;

     3)直到P为NULL并且栈为空,则遍历结束。
*/ 
void preOrderNorecursive(pT T){
    stack<pT> s;
    s.push(T);
    while(!s.empty()){
        while(T != NULL){//左子树走到尽头 
            cout<<T->x<<" ";
            T = T->lchild;
            s.push(T);
        }
        s.pop();//清除空指针
        if(!s.empty()) {
            T = s.top();
            s.pop();
            s.push(T=T->rchild);//右子树走起 
        }
    }
}

void preOrderOutT(pT T){
    if(T){
        cout<<T->x<<" ";
        preOrderOutT(T->lchild);
        preOrderOutT(T->rchild);
    }
}

/**************************************************************************/ 
/*
   非递归中序遍历:对于任一结点P,

  1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;

  2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;

  3)直到P为NULL并且栈为空则遍历结束
*/ 
void inOrderNorecursive(pT T){
    stack<pT> s;
    s.push(T);
    while(!s.empty()){
         while(T!=NULL)//左子树走到尽头 
             s.push(T=T->lchild);
         s.pop();//清除空指针
         if(!s.empty()) {
             T = s.top();
             s.pop();
             cout<<T->x<<" ";
             s.push(T = T->rchild);//访问右子树 
         }
    }
}

void inOrderOutT(pT T){
    if(T){
        inOrderOutT(T->lchild);
        cout<<T->x<<" ";
        inOrderOutT(T->rchild);
    }
}

/**************************************************************************/ 
/*
    非递归后序遍历: 
        要保证根结点在左孩子和右孩子访问之后才能访问,因此对于任一结点P,先将其入栈。
    如果P不存在左孩子和右孩子,则可以直接访问它;或者P存在左孩子或者右孩子,但是其左孩子和右孩子
    都已被访问过了,则同样可以直接访问该结点。若非上述两种情况,则将P的右孩子和左孩子依次入栈,
    这样就保证了每次取栈顶元素的时候,左孩子在右孩子前面被访问,左孩子和右孩子都在根结点前面被访问。
*/ 
void postOrderNorecursive(pT T){
    stack<pT> s;
    s.push(T);
    pT pre = NULL;//后序遍历之前输出的节点 
    while(!s.empty()){
        T = s.top();
        if(T->lchild==NULL && T->rchild==NULL ||
           (pre!=NULL && (T->lchild==pre || T->rchild==pre)) {
           cout<<T->x<<" ";
           pre = T;
           s.pop();
        } else {//依次将右子树和左子树放入栈中 
            if(T->rchild)
                s.push(T->rchild);
            if(T->lchild)
                s.push(T->lchild);
        }
    }
}

void postOrderOutT(pT T){
    if(T){
        postOrderOutT(T->lchild);
        postOrderOutT(T->rchild);
        cout<<T->x<<" ";
    }
}
/**************************************************************************/ 

int main(){
    pT T = NULL;
    buildT(T);
    /**************************************************************************/ 
    cout<<"递归先序遍历:"<<endl;
    preOrderOutT(T);
    cout<<endl;
    cout<<"非递归先序遍历:"<<endl;
    preOrderNorecursive(T);
    cout<<endl;
    /**************************************************************************/ 
    cout<<"递归中序遍历:"<<endl;
    inOrderOutT(T);
    cout<<endl;
    cout<<"非递归中序遍历:"<<endl;
    inOrderNorecursive(T);
    cout<<endl;
    /**************************************************************************/ 
    cout<<"递归后序遍历:"<<endl;
    postOrderOutT(T);
    cout<<endl;
    cout<<"非递归后序遍历:"<<endl;
    postOrderNorecursive(T);
    cout<<endl;
    /**************************************************************************/ 
    return 0;
}
/*
2 2 -1 -1 4 7 -1 -1 -1 3 4 -1 8 -1 -1 5 -1 -1
递归先序遍历:
2 2 4 7 3 4 8 5
非递归先序遍历:
2 2 4 7 3 4 8 5
递归中序遍历:
2 7 4 1 4 8 3 5
非递归中序遍历:
2 7 4 1 4 8 3 5
递归后序遍历:
7 4 2 8 4 5 3 1
非递归后序遍历:
7 4 2 8 4 5 3 1
*/

目录
相关文章
05_二叉树的层次遍历II
05_二叉树的层次遍历II
|
6月前
|
Linux
求二叉树的先序遍历
求二叉树的先序遍历
二叉树的层次遍历
层次遍历就是即逐层地,从左到右访问所有节点
二叉树的层次遍历
【C++】非递归实现二叉树的前中后序遍历
【C++】非递归实现二叉树的前中后序遍历
【C++】非递归实现二叉树的前中后序遍历
|
JavaScript 前端开发 Java
二叉树的先序、中序、后序遍历
二叉树的先序、中序、后序遍历
155 0
二叉树的先序、中序、后序遍历
|
C语言 C++
前序遍历+中序遍历重建二叉树
前序遍历+中序遍历重建二叉树
138 0
前序遍历+中序遍历重建二叉树
二叉树中序非递归遍历
二叉树中序非递归遍历 二叉树中序非递归遍历
118 0