• 二叉树的遍历总结


    二叉树的遍历真的是又简单又复杂,以他为原型可以变出好多好多题目,但是归根结底还是要非常熟悉二叉树的遍历。递归算法就不写了,那个面试写了就是凉凉。

    1. 前序遍历

     1 def preOrder(root):
     2     stack1 = []
     3     res = []
     4     cur = root
     5     while stack1 or cur:
     6         if cur:          #这一步主要是第一步放入根节点   
     7             stack1.append(cur)
     8         cur = stack1.pop() #之后每次从栈中pop数据
     9         res.append(cur.val)
    10         if cur.right:
    11             stack1.append(cur.right)
    12         if cur.left:
    13             stack1.append(cur.left)
    14         cur = None
    15     return res    

    从这里可以看出,因为是先序遍历,所以不需要保存根节点,直接push之后再pop出来。

    2. 中序遍历

     1 def inOrder(root):
     2     stack1 = []
     3     res = []
     4     cur = root
     5     while stack or cur:
     6         while cur:
     7             stack1.append(cur)
     8             cur = cur.left
     9         cur = cur.pop()
    10         res.append(cur.val)
    11         cur = cur.right
    12     return res

    从这里我们可以看出,先序遍历和中序遍历整体结构是相同的,但是这里面的细小的区别才是最重要的,也就是先序是if 中序是while 原因就是在于先序的话我直接就读到根节点的值,但是中序遍历是在读完所有左子树才会读根节点,因此使用while 一直不断地把根节点压入栈中。

    第二个区别是在最后cur 的复制中,先序让cur=None的原因是因为cur 已经被读取到了,我已经把cur的左子树和右子树压入栈,但是中序遍历中我们需要对根节点的右节点进行遍历,所以让cur = cur.right 就可以跳到第一行的while中。同样的,有了这个while 就不要判断if cur.right == None。

    3. 后序遍历

    def postOrder(root):
            stack1 = []
            res = []
            cur = root
            while stack1 or cur:
                while cur:
                    stack1.append(cur)
                    cur = cur.right if cur.left == None else cur.left
                cur = stack1.pop()
                res.append(cur.val)
                if stack1  and stack1[-1].left == cur: #  stack1[-1] 是cur的next 节点!
                    cur = stack1[-1].right
                else:
                    cur = None
            return res

    后序遍历是比较复杂的,技巧也比较多。但是三种遍历的核心在于入栈,我们一定要搞清楚为什么要入栈,入栈到底要入什么。栈的顺序便是先入后出,所以不管是先序,中序,后序,只要能把握究竟要入什么,其实就掌握了二叉树的遍历的本质。后序中因为根节点是最后需要访问的,因此要最先入栈。然后入栈的是什么呢? 是这个数的最左边的节点,和中序遍历不同,中序遍历只要找到第一个最左边的元素,后序遍历是要找到第一个左右子树都为空的节点。

    这其实可以看出,栈中保存的是下一个需要访问的节点,而里面的while 循环,主要功能就是保存我们的路径。

  • 相关阅读:
    IOS开发---菜鸟学习之路--(二十四)-iOS7View被导航栏遮挡问题的解决
    IOS开发---菜鸟学习之路--(二十三)-直接利用键值对的方式来处理数据的感想
    IOS开发---菜鸟学习之路--(二十二)-近期感想以及我的IOS学习之路
    一口一口吃掉Hexo(六)
    一口一口吃掉Hexo(二)
    setSupportActionBar(toolbar)导致程序崩溃闪退
    【原创+译文】官方文档中声明的如何创建抽屉导航栏(Navigation Drawer)
    【文章内容来自《Android 应用程序开发权威指南》(第四版)】如何设计兼容的用户界面的一些建议(有删改)
    如何为按钮设置一组不同状态的颜色
    如何避免Activity 被杀死
  • 原文地址:https://www.cnblogs.com/tjpeng/p/12802265.html
Copyright © 2020-2023  润新知