二叉树的四种遍历方式:
- 前序遍历:先访问根节点,然后前序遍历左子树和右子树;
- 中序遍历:中序遍历根结点的左子树,然后访问根节点,最后中序遍历根节点的右子树;
- 后序遍历:后序遍历根节点的左子树和右子树,最后访问根节点;
- 层序遍历:从根节点从上往下逐层遍历,在同一层按从左到右的顺序遍历。
二叉树结点的定义:
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
一、递归解法
(一)前序遍历
def preorderTraversal(root):
res = []
if root:
res.append(root.val)
res += preorderTraversal(root.left)
res += preorderTraversal(root.right)
return res
(二)中序遍历
def inorderTraversal(root):
res = []
if root:
res += inorderTraversal(root.left)
res.append(root.val)
res += inorderTraversal(root.right)
return res
(三)后序遍历
def postorderTraversal(root):
res = []
if root:
res += postorderTraversal(root.left)
res += postorderTraversal(root.right)
res.append(root.val)
return res
二、非递归解法
(一)前序遍历
def preorderTraversal(root):
res = []
stack = []
p = root
# 退出循环的条件是结点为空且栈为空
while p or len(stack):
# 迭代访问左孩子,并入栈
while p:
res.append(p.val)
stack.append(p)
p = p.left
# 直到当前结点没有左孩子,退栈,转向当前结点的右孩子
if len(stack):
p = stack.pop()
p = p.right
return res
(二)中序遍历
def inorderTraversal(root):
res = []
stack = []
p = root
while p or len(stack):
# 迭代左孩子入栈
while p:
stack.append(p)
p = p.left
# 直到当前结点没有左孩子,退栈并访问,转向当前结点的右孩子
if len(stack):
p = stack.pop()
res.append(p.val)
p = p.right
return res
(三)后序遍历
def postorderTraversal(root):
res = []
stack = []
p = root
last = None # 标记上一次访问的结点
while p or len(stack):
# 迭代左孩子入栈
while p:
stack.append(p)
p = p.left
# 当前结点没有左孩子,或左孩子已经访问过
if len(stack):
p = stack.pop()
# 当前结点没有右孩子,或右孩子已经访问过
if not p.right or p.right == last:
res.append(p.val) # 访问当前结点
last = p
p = None # 继续退栈,并且避免当前结点重复入栈
# 有右孩子,且没访问过
else:
stack.append(p) # 则当前结点入栈,先转向右孩子
p = p.right
return res
三、层序遍历
给定二叉树: [3,9,20,null,null,15,7]
3
/ \
9 20
/ \
15 7
返回:
[3,9,20,15,7]
def levelOrder(root):
res = []
if root:
queue = [root]
while len(queue):
node = queue.pop(0)
res.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return res
给定二叉树: [3,9,20,null,null,15,7]
3
/ \
9 20
/ \
15 7
返回:
[[3],
[9,20],
[15,7]]
def levelOrder(root):
res = []
if root:
queue = [root]
last = root # 记录当前层最右边的元素
tmp = []
while len(queue):
node = queue.pop(0)
tmp.append(node.val)
if node.left:
nlast = node.left # 记录下一层最右边的元素
queue.append(node.left)
if node.right:
nlast = node.right
queue.append(node.right)
# 当当前层最右边的元素出队时,说明将要开始遍历下一层的元素了
if last == node:
last = nlast
res.append(tmp)
tmp = []
return res