• 关于树的递归和迭代遍历方法


      最近在看csdn解题笔记系列文章关于树的部分,卒读之后,扪心自问:二叉树到底有多少种便利方法?每种方法又有几中实现版本?各个版本间的关系如何,有无必然联系和转化可能?那天知道晚上一点多才有一些确定性的思考结果,总结如下。

      一、树的递归遍历方法:略;

      二、树的非递归遍历方法

        (1)国内教材和网络流行的解法:二叉树的先根遍历,中根遍历,后根遍历的非递归算法 ;

        (2)自己凭直觉想了一种先序方法[1],但无法对称地推广到中序、后序,便随便翻了下师弟给的一本电子书,Knuth大弟子Sedgewick的《算法:第1-4部分》,发现一种新的,思路比较统一的先序、中序、后序遍历的形式化非递归法描述:

          1)对于根节点:
              对于前序,入栈右子树,然后左子树,然后节点;
              对于中序,入栈右子树,然后节点,然后左子树;
              对于后序,入栈节点,然后右子树,然后左子树;
          2)子树的入栈与上面是相同的,但是我们不使用递归;

      三、层次遍历,除了流行的队列法,我设计了一种基于栈的方法(其实在模拟队列),用伪代码描述,参见[2]。

      

      四、深入想下,递归和迭代的关系是什么?他们如何转化?

        首先,请看扫盲文:

          (1)尾递归对时间与空间复杂度的影响 ;

          (2)尾递归与Continuation ;

          (3)浅谈尾递归的优化方式 ;

        得到结论:只要允许使用栈(也有人叫基于栈的非递归为递推,不列入迭代范畴),所有的递归程序都可以转化成迭代,反之则不然。但是并非所有递归都必须用栈。深入学习请参考:将递归转化成迭代的通用技术 。

      五、附录:

        [1]

        root入栈

        tag:

          if (栈非空)

            弹一次栈x,访问之;

              if (x非叶子)

                x右子树入栈;

                x左子树入栈;

                goto tag;

          结束;

        [2]

        root入栈;

        if 栈(a,b,c...)非空

          连续弹栈,直至为空,得到出栈元素xi(...c,b,a);

        按出栈次序,访问xi;

        if(xi非叶子)

          xi右子树入栈;

          xi左子树入栈;

        结束;

      

  • 相关阅读:
    Code Review
    关于calendar修改前的代码和修改后的代码
    程序员必备的代码审查(Code Review)清单
    一个数组中最大子数组的和并且加上测试用例
    阅读build to win的个人感想
    结对编码(柳祎、张许君)
    Review(patener)
    Review [myself]
    Impressions
    Array
  • 原文地址:https://www.cnblogs.com/zhaoyl/p/2477901.html
Copyright © 2020-2023  润新知