data表示节点数据,left表示左孩子指针,right表示右孩子指针
class TreeNode:
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
先(根)序遍历
中(根)序遍历
后(根)序遍历
深度遍历:递归与非递归方式,使用栈模拟递归过程,实现非递归遍历,因为递归操作本身是因为计算机帮我们完成了入栈和出栈过程
广度遍历(层序遍历):使用list或者队列实现
递归,非递归(使用栈,因为递归操作是),层序遍历(list或队列)三种方式
递归方式
class TreeNode():
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
def preorder(root):
if root is not None:
print(root.data,end=' ')
preorder(root.left)
preorder(root.right)
def inorder(root):
if root is not None:
preorder(root.left)
print(root.data)
preorder(root.right)
def postorder(root):
if root is not None:
preorder(root.left)
preorder(root.right)
print(root.data)
非递归方式(使用栈)(标记法)
from collections import deque
def preorder_use_stack(root):
if not root:
return
s = deque()
s.append((root, False))
while s:
node, visted = s.pop()
if node:
if visted:
print(node.data)
else: # stack是 后进先出。所以先序:根左右出栈 -> 右左根入栈,同理中序和后续
s.append((node.right, False))
s.append((node.left, False))
s.append((node, True))
层序遍历(使用list/队列)
# 使用list完成层序遍历
def layer_order_uselist(root):
# if not root:
# return
# cur_nodes = [root]
# next_nodes = []
# while cur_nodes or next_nodes:
# print(cur_nodes)
# for node in cur_nodes:
# if node.left:
# next_nodes.append(node.left)
# if node.right:
# next_nodes.append(node.right)
# cur_nodes = next_nodes
# next_nodes = []
li = [root]
while li:
n = len(li)
for _ in range(n):
l = li.pop(0)
if l:
print(l.data)
li.append(l.left if l.left else None)
li.append(l.right if l.right else None)
# 使用队列完成层序遍历
def layer_order_usequque(root):
d = deque()
d.append(root)
while d:
node = d.popleft()
if node:
print(node.data)
d.append(node.left if node.left else None)
d.append(node.right if node.right else None)
思路:
1、使用迭代遍历方法实现(栈+标记法)
2、使用递归实现
给定一个二叉树,返回它的 后序 遍历。
示例:
输入: [1,null,2,3]
1
\
2
/
3
输出: [3,2,1]
class TreeNode:
def __init__(self, x, left=None, right=None):
self.val = x
self.left = left
self.right = right
# # 递归,后序遍历:左右根
# class Solution:
# def postorder(self, root, res):
# if not root:
# return
# self.postorder(root.left,res)
# self.postorder(root.right,res)
# print(root.val)
# res.append(root.val)
# # 后序遍历:左右根
# def postorderTraversal(self, root: TreeNode):
# res = []
# self.postorder(root, res)
# return res
# 迭代后序遍历
class Solution:
def postorderTraversal(self, root: TreeNode):
stack = deque()
res = []
stack.append((root, False))
while stack:
node, visited = stack.pop()
if node:
if visited:
res.append(node.val)
else: # 由于是用栈存储,所以后序遍历原本时左右根->变成入栈顺序根右左
stack.append((node, True))
stack.append((node.right, False))
stack.append((node.left, False))
return res
思路:
使用list/队列
给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
示例:
二叉树:[3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回其层次遍历结果:
[
[3],
[9,20],
[15,7]
]
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def levelOrder(self, root: TreeNode) -> List[List[int]]:
if not root:
return []
cur_nodes = [root]
next_nodes = []
res = []
vals = [i.val for i in cur_nodes]
res.append(vals)
while cur_nodes or next_nodes:
for node in cur_nodes:
if node.left:
next_nodes.append(node.left)
if node.right:
next_nodes.append(node.right)
if next_nodes:
res.append([i.val for i in next_nodes])
cur_nodes = next_nodes
next_nodes = []
return res
思路
递归:递归出口、子问题、返回值
翻转一棵二叉树。
示例:
输入:
4
/ \
2 7
/ \ / \
1 3 6 9
输出:
4
/ \
7 2
/ \ / \
9 6 3 1
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def invertTree(self, root: TreeNode) -> TreeNode:
if not root:
return
root.left, root.right = root.right, root.left
self.invertTree(root.left)
self.invertTree(root.right)
return root
思路:
递归:递归出口、子问题、返回值
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
示例:
给定二叉树 [3,9,20,null,null,15,7],
3
/ \
9 20
/ \
15 7
返回它的最大深度 3 。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def maxDepth(self, root: TreeNode) -> int:
if not root:
return 0
left = self.maxDepth(root.left) + 1
right = self.maxDepth(root.right) + 1
return max(left, right)
思路:
1、递归出口:序列为空的时候
2、子问题:递归地去构造左右子树
3、返回值:根节点
根据一棵树的前序遍历与中序遍历构造二叉树。
注意:
你可以假设树中没有重复的元素。
例如,给出
前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:
3
/ \
9 20
/ \
15 7
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def buildTree(self, preorder, inorder):
if not preorder:
return None
root_val = preorder[0]
root = TreeNode(root_val) # build root node
root_idx = inorder.index(root_val)
# 计算左右子树的长度
left_len = root_idx
right_len = len(inorder)-root_idx-1
# 递归构造
if left_len:
root.left = self.buildTree(preorder[1:left_len+1], inorder[0:root_idx])
if right_len:
root.right = self.buildTree(preorder[left_len+1:], inorder[root_idx+1:])
return root