zoukankan      html  css  js  c++  java
  • 遍历二叉树的非递归实现

    对于二叉树来说,只要按照下面的模板可以很容易地实现先序、中序和后序的递归遍历二叉树。

    void visit(TreeNode *node)
    {
        //operation 1
        if (node->leftChild != nullptr)
            visit(node->leftChild);
        //operation 2
        if (node->rightChild != nullptr)
            visit(node->rightChild);
        //operation 3
    }

    使用递归可以使代码变得简洁,明了。我们不用考虑计算机底层的递归工作栈是怎么实现的,只要写好递归式,给出递归终止条件,就可以把剩余的计算工作交给计算机去执行。所以说递归是个好东东啊。但是追求真相的人,往往不会满足于此的,一定弄明白背后的工作原理。

    哈哈这就是古人云:"不可去名上理会。须求其所以然。"

    OK,下面我把今晚写的遍历二叉树的非递归算法分享一下。

    TreeNode *assistStack[MAXSIZE];//辅助栈模拟系统的递归工作栈
    bool visited[MAXSIZE] = { false };//设置访问标志位
    void visit(char value)
    {
        printf("%c ", value);
    }

    先序遍历非递归实现

    void preOrderOfNonRecurrence(TreeNode *root)
    {
        int top = -1;
        TreeNode *rNode = root;
        visit(rNode->value);
        assistStack[++top] = rNode;
      //将左子树全部入栈,边入栈便访问
        while (rNode->leftChild != nullptr)
        {
            rNode = rNode->leftChild;
            printf("%c ", rNode->value);
            assistStack[++top] = rNode;
        }
      //将栈中的左子树结点依次出栈,则先进去的结点最后出来。
      //这样对每个出栈的结点,判断其是否有右子树。如果有则将每个右子树结点的左子树入栈。
      //记住只有入栈时才访问结点。
        while (top != -1)
        {
            if (assistStack[top]->rightChild != nullptr)
            {
                rNode = assistStack[top]->rightChild;
                top--;
                printf("%c ", rNode->value);
                while (rNode->leftChild != nullptr)
                {
                    rNode = rNode->leftChild;
                    printf("%c ", rNode->value);
                    assistStack[++top] = rNode;
                }
            }
            else
            {
                top--;
            }
    
        }
    }

    中序遍历非递归实现

    void inOrderOfNonRecurrence(TreeNode *root)
    {
        TreeNode *rNode = root;
        int top = -1;
        assistStack[++top] = rNode;
        while (rNode->leftChild != nullptr)
        {
            rNode = rNode->leftChild;
            assistStack[++top] = rNode;
        }
    
        while (top != -1)
        {
            rNode = assistStack[top--];
            visit(rNode->value);
            if (rNode->rightChild != nullptr)
            {
                rNode = rNode->rightChild;
                assistStack[++top] = rNode;
                while (rNode->leftChild != nullptr)
                {
                    rNode = rNode->leftChild;
                    assistStack[++top] = rNode;
                }
            }
        }
    
    }

    后序遍历非递归实现

    void postOrderOfRecurrence(TreeNode *root)
    {
        TreeNode* rNode = root;
        int top = -1;
        assistStack[++top] = rNode;
        visited[top] = false;
        while (rNode->leftChild != nullptr)
        {
            rNode = rNode->leftChild;
            assistStack[++top] = rNode;
            visited[top] = false;
        }
    
        while (top != -1)
        {
            rNode = assistStack[top];
            visited[top] = true;
            if (rNode->rightChild != nullptr)
            {
                rNode = rNode->rightChild;
                assistStack[++top] = rNode;
                visited[top] = false;
                while (rNode->leftChild != nullptr)
                {
                    rNode = rNode->leftChild;
                    assistStack[++top] = rNode;
                    visited[top] = false;
                }
            }
    
            while (visited[top] == true && top != -1)
            {
                visit(assistStack[top]->value);
                top--;
            }
    
        }
    }

    上面代码只对先序遍历的非递归实现做了注释,其它两种没有进行注释,可以对比理解一下!

    2016年3月30日补充:

    先序遍历二叉树非递归方法:

    void PreOrderOfNoRecu(BinaryTreeNode *root)
    {
        if (root == NULL)
            return;
        BinaryTreeNode *stack[100];
        int top = -1;
        for (int i = 0; i < 100; i++)
            stack[i] = NULL;
        BinaryTreeNode *p = root;
        BinaryTreeNode *q = NULL;
        stack[++top] = p;
        while (top != -1)
        {
            while (p)
            {
                visit(p->value);
                p = p->lchild;
                if (p == NULL)
                    break;
                stack[++top] = p;
            }
            q = stack[top--];
            p = q->rchild;
            if (p != NULL)
                stack[++top] = p;
        }
    }

    中序遍历二叉树非递归方法:

    void InOrderOfNoRecurrence(BinaryTreeNode *root)
    {
        if (root == NULL)
            return;
        BinaryTreeNode *stack[100];
        for (int i = 0; i < 100; i++)
            stack[i] = NULL;
        int top = -1;
        BinaryTreeNode *node = root;
        BinaryTreeNode *p = NULL, *q = NULL;
        while (node != NULL)
        {
            stack[++top] = node;
            node = node->lchild;
        }
        while (top != -1)
        {
            q = stack[top--];
            visit(q->value);
            p = q->rchild;
            while (p)
            {
                stack[++top] = p;
                p = p->lchild;
            }
        }
    }

    后序遍历二叉树非递归方法:

    void PostOrderOfNoRecurrence(BinaryTreeNode *root)
    {
        if (root == NULL)
            return;
        BinaryTreeNode *stack[100];
        bool visited[100];
        for (int i = 0; i < 100; i++)
        {
            stack[i] = NULL;
            visited[i] = false;
        }
        int top = -1;
        BinaryTreeNode *p, *q;
        BinaryTreeNode *node = root;
        while (node)
        {
            stack[++top] = node;
            node = node->lchild;
        }
    
        while (top != -1)
        {
            q = stack[top];
            visited[top] = true;
            p = q->rchild;
            while (p)
            {
                stack[++top] = p;
                p = p->lchild;
            }
    
            while (visited[top] && top != -1)
            {
                q = stack[top];
                visit(q->value);
                visited[top] = false;
                top--;
            }
        }
    }
  • 相关阅读:
    suse12安装详解
    Centos7上部署openstack mitaka配置详解(将疑难点都进行划分)
    菜鸟帮你跳过openstack配置过程中的坑[文末新添加福利]
    openstack中dashboard页面RuntimeError: Unable to create a new session key. It is likely that the cache is unavailable.
    Multiple network matches found for name 'selfservice', use an ID to be more specific.报错
    查看 SELinux状态及关闭SELinux
    SELinux深入理解
    IP地址、子网掩码、网络号、主机号、网络地址、主机地址
    Oracle job procedure 存储过程定时任务
    POI文件导出至EXCEL,并弹出下载框
  • 原文地址:https://www.cnblogs.com/tgycoder/p/4970287.html
Copyright © 2011-2022 走看看