遍历二叉树的非递归实现

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

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--;
        }
    }
}