(1)前中后序的递归遍历
前中后序的不同之处在于根节点的访问顺序
# 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: Optional[TreeNode]) -> List[int]:
res = []
def helper(root: Optional[TreeNode]) -> List[int]:
if root == None:
return
res.append(root.val)
helper(root.left)
helper(root.right)
helper(root)
return res
(2)144.前序遍历-迭代法![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/60623fe9aae0a580e1ed48b2dc8e7d16.gif#pic_center)
符合后进先出的原则 先序遍历 右节点先入栈 左节点再入栈
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if root == None:
return []
stack = [root]
res = []
while stack:
node = stack.pop()
res.append(node.val)
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
return res
(3)145.后序遍历-迭代法
相较于前序的根-左-右
后序遍历不仅变为了左-右-根,同时在每个子树的遍历过程中同样发生了相同逻辑的变化,所以入栈的左右子树调换的同时,最后的结果也要逆置
class Solution:
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
stack, res = [root], []
while stack:
node = stack.pop()
res.append(node.val)
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return res[::-1]
(4)94.中序遍历-迭代法
相较于前序遍历,中序遍历要先找到当前最左端元素,然后处理父节点和右节点,所以当前栈顶元素的执行和出栈要遵循规则
class Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
# 中序遍历 此时不能先将Root加入栈
stack, res = [], []
cur = root
while cur or stack:
# 迭代直到访问到最左边的节点
if cur:
stack.append(cur)
cur = cur.left
# 到达左节点之后开始处理栈内顶端元素
else:
cur = stack.pop()
res.append(cur.val)
# 取当前栈顶元素的右节点
cur = cur.right
return res
(5)105.二叉树层次遍历
节点出队时先入先出,并顺势压入子节点
class Solution:
def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
if not root:
return []
res = []
que = deque( [root] )
while que:
floor = []
for _ in range(len(que)):
node = que.popleft()
floor.append(node.val)
if node.left:
que.append(node.left)
if node.right:
que.append(node.right)
res.append(floor)
return res
(6)235.二叉搜索树的最近公共祖先
给定一棵树找出两个节点最近的公共祖先,由于树结构是搜索树,所有存在左子树<父节点<右子树的情况,要是当前节点都大于二者,就向左找,都小于二者就向右找,如果出现了左右夹在中间的情况,那就是这个点了呗,因为左右两节点分支了,那岂不是自己就是父节点嘛
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
while root:
if root.val > max(p.val, q.val):
root = root.left
elif root.val < min(p.val, q.val):
root = root.right
else:
return root
return None
(7)98.验证搜索二叉树
二叉搜索树不存在等值元素,且中序遍历为升序,验证中序遍历即可
class Solution:
def isValidBST(self, root: Optional[TreeNode]) -> bool:
res = []
def helper(root: Optional[TreeNode]) -> None:
if root is None:
return
if root.left:
helper(root.left)
res.append(root.val)
if root.right:
helper(root.right)
helper(root)
if len( list(set(res)) ) != len(res):
return False
return res == sorted(res)