前、后、中序遍历的递归和迭代代码框架
前:根左右
后:左右根
中:左根右
递归版本对于三种方法具有一致性:
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def preorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
def helper(proot):
if proot is None:
return
res.append(proot.val) # 移动这个append-"根"即可
left = helper(proot.left)
right = helper(proot.right)
helper(root)
return res
迭代方法各异,但前、后序相似,中序单独考虑
1. 前序(“根右左”)
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def preorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = [] # 里面放val
if root is None:
return res
stack = [root] # 先进后出,所以右先进,这样右后出。
while stack:
node = stack.pop()
res.append(node.val)
if node.right is not None:
stack.append(node.right)
if node.left is not None:
stack.append(node.left)
return res
2. 后序("左右根"加反转)
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def postorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = [] # 里面放val
if root is None:
return res
stack = [root]
while stack:
node = stack.pop()
if node.left is not None: # left、right顺序和前序相反
stack.append(node.left)
if node.right is not None:
stack.append(node.right)
res.append(node.val) # 左右根
return res[::-1] # 反转
3. 中序(不要求掌握,略,省的影响之前背的框架)
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def inorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
res = []
if root is None:
return res
stack = []
cur = root
while stack or cur:
while cur: # 把当前节点及其左节点、左节点的左节点...放入stack
stack.append(cur)
cur = cur.left
cur = stack.pop()
res.append(cur.val) # 取出最后一个左节点,并将其值放入res
cur = cur.right # 取一次右节点
return res
所有方法:
时间复杂度:访问每个节点恰好一次,时间复杂度为
O
(
N
)
O(N)
O(N) ,其中
N
N
N 是节点的个数,也就是树的大小。
空间复杂度:取决于树的结构,最坏情况存储整棵树,因此空间复杂度是
O
(
N
)
O(N)
O(N)。
汇总
# 二叉树节点类
class TreeNode(object):
def __init__(self, val):
self.val = val
self.left = None
self.right = None
class Solution(object):
def preorder(self, root):
# 二叉树的前中后序遍历-递归版
res = []
def helper(root):
if root is None:
return
res.append(root.val) # 中、后序移动此行即可
left = helper(root.left)
right = helper(root.right)
helper(root)
return res
def preorder_list(self, root):
# 二叉树的前序遍历-非递归
# 根右左
# append、right、left
res = []
stack = [root]
if root is None:
return res
while stack:
tmp = stack.pop()
res.append(tmp.val) # append、right、left
if tmp.right is not None:
stack.append(tmp.right)
if tmp.left is not None:
stack.append(tmp.left)
return res
def lastorder_list(self, root):
# 二叉树的后序遍历-非递归
# 左右根 加 反转
# left、right、append + 反转
res = []
stack = [root]
if root is None:
return res
while stack:
tmp = stack.pop()
if tmp.left is not None:
stack.append(tmp.left)
if tmp.right is not None:
stack.append(tmp.right)
res.append(tmp.val)
return res[::-1]
def hier_simple(self, root):
# 二叉树的层次遍历-简单一点
# 正常 根左右,用队列
res = []
queue = [root] # 队列
if root is None:
return res
while queue:
tmp = queue.pop(0)
res.append(tmp.val) # 和前序的区别,前序是append、right、left
if tmp.left is not None:
queue.append(tmp.left)
if tmp.right is not None:
queue.append(tmp.right)
return res
def hier_comple(self, root):
# 二叉树的层次遍历-与上面代码主体部分完全一致
# 多了个tmp_list与length的range循环而已
res = []
queue = [root]
if root is None:
return res
while queue:
tmp_list = []
length = len(queue)
for i in range(length):
# 将目前queue中的节点全部吐到tmp_list中,相当于每一行的节点都单独吐到tmp_list中
# 但又要保证新加入的节点不被吐出,所以固定住原来的queue的长度,只吐原来queue中所存在的节点
tmp = queue.pop(0)
tmp_list.append(tmp.val)
if tmp.left is not None:
queue.append(tmp.left)
if tmp.right is not None:
queue.append(tmp.right)
res.append(tmp_list[:])
return res