【leetcode 144、94、145、102】【二叉树前、中、后序以及层次遍历】

leetcode 【二叉树的各种遍历】

1. 前序遍历

题目链接

https://leetcode-cn.com/problems/binary-tree-preorder-traversal/


解题思路与代码思路:

递归法

前序遍历就是“根节点–左子树–右子树”的顺序去遍历整棵树,递归可以完美匹配这个过程。

迭代法

把递归所隐含的栈结构构建出来,模拟递归过程。只要左子树为空就pop出来,然后看右边。


代码:

递归法
class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        def preorder(root):
            if not root:
                return 
            res.append(root.val)
            preorder(root.left)
            preorder(root.right)
        
        res = []
        preorder(root)
        return res
迭代法
  • 辅助指针写法
class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        res = list()
        if not root:
            return res
        
        stack = []
        node = root
        while stack or node:
            while node:                #移动指针node,重复的找左树直到为空
                res.append(node.val)   #当前值存入result
                stack.append(node)     #加入栈中
                node = node.left       #跳到左子树
            node = stack.pop()         # 遇到空的情况会一直pop,最后又回到根节点
            node = node.right          
        return res

  • 利用了栈的属性
class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        res = list()
        if not root:
            return res
        
        stack = [root]
        while stack:
            node = stack.pop()
            if node:
                res.append(node.val)
                if node.right:        #先放右节点,后放左节点,因为会把最新进栈的pop出来存入res
                    stack.append(node)
                if node.left:
                    stack.append(node.left)
        return res

复 杂 度 分 析 : \color{red}{复杂度分析:}
  1. 递归法
  • 时间复杂度:O(N),遍历每个节点
  • 空间复杂度:O(N),递归中栈的开销,平均情况下为 O(logn),最坏情况下树呈现链状,为 O(n)
  1. 迭代法
  • 时间复杂度:O(N),遍历每个节点
  • 空间复杂度:O(N),递归中栈的开销,平均情况下为 O(logn),最坏情况下树呈现链状,为 O(n)

2. 中序遍历

解题思路与代码思路:

递归法

递归法只需要调整前序遍历的res.append(root.val)的位置即可完成,所以不多写了。

迭代法

迭代法其实就是模拟递归法的入栈出栈过程,因为是左—中---右的顺序,所以就先把节点入栈,不断进入左子树入栈,直到为空,就可以出栈存入到res当中,并且转移到该节点的右树上。


代码:

迭代法
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        res = list()
        if not root:
            return res
        
        stack = []
        node = root
        while stack or node:
            while node:
                stack.append(node)
                node = node.left
            node = stack.pop()
            res.append(node.val)
            node = node.right
        return res


复 杂 度 分 析 : \color{red}{复杂度分析:}
  • 时间复杂度:O(N)
  • 空间复杂度:O(N)

3. 后序遍历

解题思路与代码思路:

递归法

递归法只需要调整前序遍历的res.append(root.val)的位置即可完成,所以不多写了。

迭代法

迭代法有两种方式:

  1. 反向输出
    后序遍历的输出是《左右根》的方式输出,我们可以按照《根右左》的方式去存入栈,然后反向输出就可以了。

  2. flag标识辅助记录
    创建一个flag标识,记录是否遍历过一次本节点,这里我们使用了元组去记录,更加方便


代码:

迭代法
class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        if not root: return []
        stack,res = [(0,root)],[]
        while stack:
            flag,node = stack.pop()
            if not node: continue
            if flag == 1:
                res.append(node.val)
            else:
                stack.append((1,node))
                stack.append((0,node.right))
                stack.append((0,node.left))
        return res


复 杂 度 分 析 : \color{red}{复杂度分析:}
  • 时间复杂度:O(N)
  • 空间复杂度:O(N)

4. 层次遍历

解题思路与代码思路:

队列法

层次遍历使用了广度优先搜索,广度优先搜索主要使用队列实现,collection.dequeue.


代码:

队列法
def levelOrder(self,root):
    if not root:return []
    
    res,q = [],[root]
    while q:
        n = len(q)
        level = []
        for i in range(n):
            node = q.pop(0)
            level.append(node.val)
            if node.left:
                q.append(node.left)
            if node.right:
                q.append(node.right)
        res.append(level)
    return res


复 杂 度 分 析 : \color{red}{复杂度分析:}
  • 时间复杂度:O(N)
  • 空间复杂度:O(N)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值