美文网首页二叉树之下
二叉树前序(先序)中序后序遍历 C++递归和非递归实现

二叉树前序(先序)中序后序遍历 C++递归和非递归实现

作者: shu2man | 来源:发表于2018-03-30 12:02 被阅读300次

如下图,对图中二叉树遍历:

先序为:ABDNCEFGHIJKLMOQP
中序为:DNBCGFEAHJKILOQMP
后序为:NDGFECBKJQOPMLIHA

二叉树示意.jpg

假设树节点如下:

struct Node{
    char data;
    Node *left;
    Node *right;
};

递归实现

先序

void preOrder(Node *root){
    cout<<root->data;
    preOrder(root->left);
    preOder(root->right);
}

中序

void inOrder(Node *root){
    preOrder(root->left);
    cout<<root->data;
    preOder(root->right);
}

后序

void postOrder(Node *root){
    preOrder(root->left);
    preOder(root->right);
    cout<<root->data;
}

非递归实现

先序

对于任一结点P:
1)访问结点P,并将结点P入栈;
2)判断结点P的左孩子是否为空,若为空,则取栈顶结点并进行出栈操作,并将栈顶结点的右孩子置为当前的结点P,循环至1);若不为空,则将P的左孩子置为当前的结点P;
3)直到P为NULL并且栈为空,则遍历结束。

void preOrderS(Node *root)   
{
    stack<Node*> s;
    Node *p=root;
    while(p!=NULL||!s.empty())
    {
        while(p!=NULL)
        {
            cout<<p->data<<" ";
            s.push(p);
            p=p->left;
        }
        if(!s.empty())
        {
            p=s.top();
            s.pop();
            p=p->right;
        }
    }
}

中序

对于任一结点P,
1)若其左孩子不为空,则将P入栈并将P的左孩子置为当前的P,然后对当前结点P再进行相同的处理;
2)若其左孩子为空,则取栈顶元素并进行出栈操作,访问该栈顶结点,然后将当前的P置为栈顶结点的右孩子;
3)直到P为NULL并且栈为空则遍历结束。

void inOrderS(Node *root){
    stack<Node*> s;
    Node *p=root;
    while(p!=NULL||!s.empty()){
        while(p!=NULL)){
            s.push(p);
            p=p->left;
        }
        if(!s.empty()){
            p=s.top();
            s.pop();
            cout<<p->data;
            p=p->right;
        }
    }
}

后序

因为后序非递归遍历二叉树的顺序是先访问左子树,再访问右子树,最后访问根节点。当用堆栈来存储节点,必须分清返回根节点时,是从左子树返回的,还从右子树返回的。所以,使用辅助指针r,其指向最近访问过的节点。也可以在节点中增加一个标志域,记录是否已被访问。

void PostOrderS(Node *root) {
    Node *p = root, *r = NULL;
    stack<Node*> s;
    while (p!=NULL || !s.empty()) {
        if (p!=NULL) {//走到最左边
            s.push(p);
            p = p->left;
        }
        else {
            p = s.top();
            if (p->right!=NULL && p->right != r)//右子树存在,未被访问
                p = p->right;
            else {
                s.pop();
                visit(p->val);
                r = p;//记录最近访问过的节点
                p = NULL;//节点访问完后,重置p指针
            }
        }//else
    }//while
}

相关文章

  • 各种二叉树遍历

    C++实现,二叉树的递归、非递归版本的前序、中序、后序遍历。

  • goLang 二叉树遍历(递归 非递归 前序遍历 中序遍历 后序

    goLang 二叉树遍历(递归 非递归 前序遍历 中序遍历 后序遍历 层序遍历) 前序遍历 中序遍历 后序遍历 代...

  • 算法之二叉树

    二叉树之C++实现 创建二叉树 复制二叉树 先序遍历 递归实现 非递归实现 中序遍历 递归实现 非递归实现 后序遍...

  • 二叉树遍历-JAVA实现

    基础二叉树 二叉树遍历分为前序、中序、后序递归和非递归遍历、还有层序遍历。 前序递归遍历算法:访问根结点-->递归...

  • 二叉树的操作

    /*主要内容:1、实现二叉树的先序、中序、后序遍历,包括递归方式和非递归方式*/ 实现二叉树的先序、中序、后序遍历...

  • 树的遍历,golang实现

    先序,递归 中序,递归 后序,递归 先序,非递归 中序,非递归 后序,非递归 层序遍历

  • 根据两个traversal恢复二叉树

    已知前序和中序遍历: 递归版本: 非递归版本: 已知后序和中序遍历:非递归:

  • 二叉树的各类遍历方法

    二叉树的遍历主要有四种:前序、中序、后序、层序。 遍历的实现方式主要是:递归和非递归。递归遍历的实现非常容易,非递...

  • 二叉树前、中、后序遍历、层次遍历

    1、前序遍历 非递归:利用Stack实现 递归 2、中序遍历 非递归:利用Stack实现 递归: 3、后序遍历 非...

  • 二叉树的遍历

    非递归前序遍历 非递归中序遍历 非递归后序遍历 层序遍历

网友评论

    本文标题:二叉树前序(先序)中序后序遍历 C++递归和非递归实现

    本文链接:https://www.haomeiwen.com/subject/elobcftx.html