剑指offer33-二叉树的遍历

leetcode144-二叉树前序遍历

方法二:辅助栈

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        # 
        stack,res = [],[]
        stack.append(root)
        while stack:
            node = stack.pop()
            if node:
                res.append(node.val)
            if node.left:
                stack.append(node.left)
            if node.right:
                stack.append(node.right)
        return res

二叉树中序遍历

方法一:递归
方法二:辅助栈

时间复杂度o(n),空间复杂度o(n)

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        stack,res = [],[]
        while stack or root:
            if root:
                stack.append(root)
                root = root.left
            else:# 不断往左走
                tmp = stack.pop()# 为空则从stack弹出保存最后一个节点的值
                res.append(tmp.val)
                root = tmp.right# 然后转向右边再持续整个过程
        return res

二叉树后序遍历

方法一:递归*

思路:
通过递归判断所有子树的正确性(后序遍历是否满足二叉搜索树的定义)
递归解析:
终止条件: i>=j,说明此子树节点数量<=1
递推工作:
1. 划分左右子树: 遍历[i,j]区间的元素,寻找第一个大于跟节点的节点,索引记为m。所以左子树区间[i,m-1],右子树区间[m,j],跟索引j
2. 判断是否为二叉搜索树:

返回值:

  1. p == j 判断此树是否正确
  2. recur(i,m-1) 判断此树的左子树是否正确
  3. recur(m,j-1) 判断此树的右子树是否正确

时间复杂度:o(n^2) 每次调用recur(i,j)减去一个跟节点,o(n);最差情况下每轮遍历树所有节点(树退化为链表),o(n)
空间复杂度:o(n) 最差情况下,递归深度为n

class Solution:
    def verifyPostorder(self, postorder: List[int]) -> bool:
        def recur(i,j):
            if i >= j:
                return True
            p = i
            while postorder[p] < postorder[j]:
                p += 1
            m = p
            while postorder[p] > postorder[j]:
                p += 1
            return p == j and recur(i,m-1) and recur(m,j-1)
        return recur(0,len(postorder)-1) 
            

方法二:辅助单调栈
补充知识:单调栈
后序遍历倒序:在这里插入图片描述
设后序遍历倒序列表[rn,rn-1,…,r1],遍历此列表,设索引为i
若为二叉搜索树,则:
节点值ri > ri+1,ri为ri+1的右子节点
节点值ri<ri+1,ri为某节点root的左子节点
当遍历时遇到递减节点ri< ri+1,对于后序遍历中节点ri右边的任意节点rx属于[ri-1,…,r1],rx < root
借助单调栈:

  1. 单调栈stack存储值递增的节点
  2. 每当遇到值递减的节点ri,通过出栈跟新节点ri的父节点root
  3. 每轮判断ri和root的值关系
    算法流程:
  4. 初始化:
  5. 倒序遍历,记每个节点为ri(a. 判断,ri>root,返回false;b. 更新root,c。出栈)
  6. 遍历完成,返回true
    时间复杂度:o(n)
    空间复杂度:o(n)
class Solution:
    def verifyPostorder(self, postorder: List[int]) -> bool:
        stack,root = [],float("+inf")
        for i in range(len(postorder)-1,-1,-1):
            if postorder[i] > root:return False
            while (stack and postorder[i] < stack[-1]):
                root = stack.pop()
            stack.append(postorder[i])
        return True
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []
        stack = [root]
        res = []
        while stack:
            s = stack.pop()
            res.append(s.val)
            if s.left:
                stack.append(s.left)
            if s.right:
                stack.append(s.right)
        return res[::-1]# 在前序遍历中,将Left与right交换,输出反转的树
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值