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

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

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

      算法是思想:

        设置一个栈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定义别名,这样改起来真的很麻烦,还好代码很短。

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

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

  • 相关阅读:
    重载与重写的区别
    类加载过程(clinit()),对象实例化过程(init())
    [c++]内联函数
    [c++]默认参数
    【一套C语言控制台的输出框代码】
    [windows]部分前缀以及其意义
    后缀名“.dll .obj .lib”和“ .so .o .a”文件的区别含义
    为什么变量一定要声明?
    wndows程序设计之书籍知识与代码摘录-封装一个类似printf的messagebox
    wndows程序设计之书籍知识与代码摘录-获取视屏显示器像素等参数GetsystemMetrics
  • 原文地址:https://www.cnblogs.com/ITgaozy/p/5163039.html
Copyright © 2011-2022 走看看