二叉树的迭代遍历
参考:代码随想录https://www.programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E8%BF%AD%E4%BB%A3%E9%81%8D%E5%8E%86.html
1 迭代写法
1.1 前序遍历
https://leetcode.cn/problems/binary-tree-preorder-traversal/
入栈顺序:先右再左
class Solution(object):
def preorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
if not root:
return root
st = [root]
while st:
cur = st.pop()
res.append(cur.val)
if cur.right:
st.append(cur.right)
if cur.left:
st.append(cur.left)
return res
1.2 中序遍历
https://leetcode.cn/problems/binary-tree-inorder-traversal/description/
中序遍历不能套用前序的办法。这是因为前序遍历中访问节点(遍历节点)和处理节点(将元素放进result数组中)可以同步处理,但是中序就无法做到同步!
中序遍历是左中右,但迭代顺序肯定是先根节点。所以需要用指针遍历来帮助访问结点,栈来处理结点上的元素
class Solution(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
if not root:
return res
st = []
cur = root
while st or cur:
if cur:
st.append(cur)
cur = cur.left
else:
cur = st.pop()
res.append(cur.val)
cur = cur.right
return res
1.3 后序遍历
class Solution(object):
def postorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
if not root:
return res
cur = root
st = []
prev = None
while cur or st:
if cur:
st.append(cur)
cur = cur.left
else:
cur = st.pop()
#现在需要确定的是是否有右子树,或者右子树是否访问过
#如果没有右子树,或者右子树访问完了,也就是上一个访问的节点是右子节点时
#说明可以访问当前节点
if not cur.right or cur.right == prev:
res.append(cur.val)
prev = cur
cur = None
else:
st.append(cur)
cur = cur.right
return res
2 迭代遍历的应用
一般需要用到遍历中结点序号,或者要用到上一个结点信息的,用迭代遍历会更容易理解。
递归也可以做,需要借助外部变量来记录中间结果,有点麻烦。
2.1 二叉搜索树中第K小的元素
class Solution(object):
def kthSmallest(self, root, k):
"""
:type root: TreeNode
:type k: int
:rtype: int
"""
st = []
if not root:
return
cur = root
idx = 1
while st or cur:
if cur:
st.append(cur)
cur = cur.left
else:
cur = st.pop()
if idx == k:
return cur.val
idx += 1
cur = cur.right
return
2.2 验证二叉搜索树
https://leetcode.cn/problems/validate-binary-search-tree/
class Solution(object):
def isValidBST(self, root):
"""
:type root: TreeNode
:rtype: bool
"""
if not root:
return True
prev = None
cur = root
st = []
while cur or st:
if cur:
st.append(cur)
cur = cur.left
else:
cur = st.pop()
if prev and cur.val <= prev.val:
return False
prev = cur
cur = cur.right
return True