代码随想录算法训练营第十四天| 二叉树的递归遍历、迭代遍历、统一迭代

基础知识

满二叉树

只有度为2或者0的节点,并且所有度为0的节点都在一层

完全二叉树

除了最低层,每一层都填满了,并且最底层也是从左到右填的

二叉搜索树

左节点永远小于父节点,父节点永远小于右节点

平衡二叉树

左右高度相差不超过1

144. 二叉树的前序遍历

题目描述: 144. 二叉树的前序遍历.

解法

递归
class Solution(object):
    def preorderTraversal(self, root):
        if not root:
            return []
        left = self.preorderTraversal(root.left)
        right = self.preorderTraversal(root.right)

        return [root.val] + left + right

迭代
class Solution(object):
    def preorderTraversal(self, root):
        if not root:
            return []
        res = []
        st = [root]
        while st:
            node = st.pop()
            res.append(node.val)
            if node.right:
                st.append(node.right)
            if node.left:
                st.append(node.left)
        return res

迭代的主要思路也比较简单,就是我每次只出一个栈(因此root要先放进去),然后再考虑被拿出来的这个有没有左右节点,然后把右节点先放进去(因为顺序是中、左、右,那么放到栈里的顺序就应该是先右后左)

统一的迭代
class Solution(object):
    def preorderTraversal(self, root):
        res = []
        st = []
        if root:
            st.append(root)
        while st:
            node = st.pop()
            if node:
                if node.right:
                    st.append(node.right)
                if node.left:
                    st.append(node.left)
                st.append(node)
                st.append(None)
            else:
                node = st.pop()
                res.append(node.val)
        return res

统一的迭代的想法就是,将遍历的过程和处理的过程分开来,先遍历,然后父节点之后紧跟一个none来表示这个是父节点,每一个子节点都会变为父节点,所以就算某个节点是某个节点的左节点或者右节点,他最后都会成为一个父节点,这样在遍历他的时候就要先存储再操作

145. 二叉树的后序遍历

题目描述: 145. 二叉树的后序遍历.

解法

递归
class Solution(object):
    def postorderTraversal(self, root):
        if not root:
            return []

        left = self.postorderTraversal(root.left)
        right = self.postorderTraversal(root.right)
        return left + right + [root.val]
迭代
class Solution(object):
    def postorderTraversal(self, root):
        if not root:
            return []
        res = []
        st=[root]
        while st:
            node = st.pop()
            res.append(node.val)
            if node.left:
                st.append(node.left)
            if node.right:
                st.append(node.right)
        return res[::-1]

前序遍历中的顺序是:父、左、右,而后序遍历的顺序是:左、右、父,我们可以将前序遍历的内容中,左右反过来,然后再把结果翻转过来,就是后序遍历

统一迭代
class Solution(object):
    def postorderTraversal(self, root):
        res = []
        st = []
        if root:
            st.append(root)
        while st:
            node = st.pop()
            if node:
                st.append(node)
                st.append(None)
                if node.right:
                    st.append(node.right)
                if node.left:
                    st.append(node.left)
            else:
                node = st.pop()
                res.append(node.val)
        return res

94. 二叉树的中序遍历

题目描述: 94. 二叉树的中序遍历.

解法

递归
class Solution(object):
    def inorderTraversal(self, root):
        if not root:
            return []
        left = self.inorderTraversal(root.left)
        right = self.inorderTraversal(root.right)
        return left + [root.val] + right
迭代
class Solution(object):
    def inorderTraversal(self, root):
        res = []
        cur = root
        st = []
        while cur or st:
            if cur:
                st.append(cur)
                cur = cur.left
            else:
                cur = st.pop()
                res.append(cur.val)
                cur = cur.right
        return res

在前序遍历中,由于父节点是先被处理到的,也会被先遍历到,所以整个流程比较简单,但是在中序遍历中,父节点会先被“遍历”到,但是处理则需要先处理左节点,所谓的处理就是获得数值或者是各种操作之类的。所以大致的流程就是,遍历根节点的左节点,并且把每个父节点都加入到栈中,直到遍历到空的位置,这时就可以从栈取出节点进行处理,然后处理这个节点的右节点,当指针指向的节点为空的时候,从栈中取出的节点一定是上一个处理的节点的父节点。

统一的迭代
class Solution(object):
    def inorderTraversal(self, root):
        res = []
        st = []
        if root:
            st.append(root)
        while st:
            node = st.pop()
            if node:
                if node.right:
                    st.append(node.right)
                st.append(node)
                st.append(None)
                if node.left:
                    st.append(node.left)
            else:
                node = st.pop()
                res.append(node.val)
        return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值