二叉树的非递归遍历

  想比递归遍历二叉树,非递归遍历显得有些复杂。今天我们介绍非递归遍历的中序算法。

  我们知道递归是靠栈来实现的。递归遍历是将复杂的算法交给了工作栈,算法比较容易,但系统开销大,而非递归遍历是由我们来实现复杂的操作,这样算法难度增加,但系统开销较小。

  算法是思想:

    设置一个栈stack,current为指向根节点的指针。

    current非空时,将current指针入栈,将current指向左孩子。(这里将current和左孩子入栈,current在下,左孩子在上。)

    当current为空时,current为栈顶的右孩子,栈顶弹出两次。(因为是中序遍历,我们输出顺序是左根右,所以我们先输出左孩子,在输出根。故两次出栈)

    当current和stack都为空时结束。(此时遍历树完成)

我们看一下c的实现代码

void h_print(Tree * tree)//非递归方法遍历二叉树,中序遍历
{
    Stack stack;
    Node * current = tree->root;

    s_init(&stack);

    while ( current != NULL || !s_empty(&stack) )
    {
        if ( current != NULL )//先将父节点入栈,然后是它的左子树
        {
            s_push(&stack, current);
            current = current->left;
        }
        else//当左子树为NULL时,出栈两次,将当前节点的父节点的右子树入栈
        {
            printf("%-5d", s_top(&stack)->data);
            s_pop(&stack);
            if ( s_empty(&stack) )
                continue;
            current = s_top(&stack)->right;
            printf("%-5d", s_top(&stack)->data);
            s_pop(&stack);
        }
    }
}

这样我们就实现了非递归的中序遍历。

  栈在之前的博客里已经实现了。很简单,不过我的实现有个问题,数据域没有用typedef定义别名,这样改起来真的很麻烦,还好代码很短。

  前段时间看过一篇博客,好像叫:我最终成了我所讨厌的人。博客说的是关于他的一些工作经历,很多时候我觉得多此一举的事或者很笨的事,都是我的水平不够理解别人的代码跟我考虑的不周全所造成的。真要我来完成这个任务时,我很难做的比他好。

  我要时刻告诫着自己,谦虚,认真,不断提高。

 

posted @ 2016-01-27 13:59  Covit  阅读(684)  评论(0编辑  收藏  举报