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--;
            }
        }
    }
  • 相关阅读:
    Medication Reconciliation Overview
    The Info-Button Standard: Bring Meaningful Use To the Patient
    Configuring Time in Windows 7 and Win 200
    oracle补齐日期
    mysql-proxy
    Oracle:Authid Current_User的使用
    oracle的sqlldr常见问题
    hive的select重命名字段显示成中文
    python访问hive
    禁用SSL v2.0、SSL v3.0协议
  • 原文地址:https://www.cnblogs.com/tgycoder/p/4970287.html
Copyright © 2011-2022 走看看