清单
● 理论基础
● 递归遍历
● 迭代遍历
● 统一迭代
理论基础
二叉树的种类:
满二叉树/ 完全二叉树/ 二叉搜索树/ 平衡二叉搜索树
二叉树的存储方式:
二叉树可以链式存储,也可以顺序存储
如果使用数组存储二叉树
如果父节点的数组下标是 i,那么它的左孩子就是 i * 2 + 1,右孩子就是 i * 2 + 2
二叉树的遍历方式
- 深度优先遍历: 先往深走,遇到叶子结点再往回走。
- 广度优先遍历: 一层一层的去遍历。
1. 二叉树的递归遍历
● 144 二叉树的前序遍历
● 145 二叉树的后续遍历
● 94 二叉树的中序遍历
2. 思路
- 确定递归函数的参数和返回值
- 确定终止条件
- 确定单层递归的逻辑
3. 代码实现
#144 二叉树的前序遍历
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]):
if not root:
return []
left = self.preorderTraversal(root.left)
right = self.preorderTraversal(root.right)
return [root.val] + left + right
#145 二叉树的后序遍历
class TreeNode:
def __init__(self, val = 0, left = None, right = None):
self.val = val
self.left = left
self.right = right
class Solution:
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
left = self.postorderTraversal(root.left)
right = self.postorderTraversal(root.right)
return left + right + [root.val]
#94 二叉树的中序遍历
class TreeNode:
def __init__(self, val = 0, left = None, right = None):
self.val = 0
self.left = left
self.right = right
class Solution:
def inorderTraversal(self, root:Optional[TreeNode]):
if not root:
return []
left = self.inorderTraversal(root.left)
right = self.inorderTraversal(root.right)
return left + [root.val] + right
2. 二叉树的迭代遍历
1. 题目
● 144 二叉树的前序遍历
● 145 二叉树的后续遍历
● 94 二叉树的中序遍历
2. 思路
递归的实现: 每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,递归返回,从栈顶弹出上一次递归的各项参数。
#前序遍历 - 访问顺序和读取顺序一致,因此使用node记录每一次弹出元素。最终return结果为中左右,因此入栈顺序应该为右左中
#后续遍历 访问顺序同读取顺序不一致,最终return结果为左右中,观察可通过更改前序遍历部分代码实现,即更改入栈顺序为左右中,最后return结果反转即可
#中序遍历 访问顺序同读取顺序不一致,借用指针来记录访问顺序,先遍历到二叉树最底部依次记录左侧元素,
3. 代码实现
#144 二叉树的前序遍历
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]:
if not root:
return []
stack = [root]
result = []
while stack:
node = stack.pop()
result.append(node.val)
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
return result
#145 二叉树的后序遍历
class TreeNode:
def __init__(self, val = 0 , left = None, right = None):
self.val = val
self.left = left
self.right = right
class Solution:
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
stack = [root]
result = []
while stack:
node = stack.pop()
result.append(node.val)
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return result[::-1]
#94 二叉树的中序遍历
class TreeNode:
def __init__(self, val = 0, left = None, right = None):
self.val = val
self.left = left
self.right = right
class Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
#访问顺序和入栈顺序不一致,使用指针记录访问,所以此时stack为空,便于记录访问顺序
if not root:
return []
stack = []
result = []
cur = root #从二叉树头节点开始
while cur or stack:
if cur:
stack.append(cur)
cur = cur.left
else:
cur = stack.pop()
result.append(cur.val)
cur = cur.right
return result
统一迭代
1. 题目
● 144 二叉树的前序遍历
● 145 二叉树的后续遍历
● 94 二叉树的中序遍历
2. 思路
通过将要处理的节点放入栈之后,紧接着放入一个空指针作为标记,达到统一迭代代码的实现
3. 代码实现
#144 二叉树的前序遍历
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]:
if not root:
return []
stack = [root]
result = []
while stack:
node = stack.pop()
if node != None:
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
stack.append(node)
stack.append(None)
else:
node = stack.pop()
result.append(node.val)
return result
#145 二叉树的后序遍历
class TreeNode:
def __init__(self, val = 0, left = None, right = None):
self.val = val
self.left = left
self.right = right
class Solution:
def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
stack = [root]
res = []
while stack:
node = stack.pop()
if node != None:
stack.append(node)
stack.append(None)
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
else:
node = stack.pop()
res.append(node.val)
return res
#94 二叉树的中序遍历
class TreeNode:
def __init__(self, val = 0, left = None, right = None):
self.val = val
self.left = left
self.right = right
class Solution:
def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
stack = [root]
res = []
while stack:
node = stack.pop()
if node != None:
if node.right:
stack.append(node.right)
stack.append(node)
stack.append(None)
if node.left:
stack.append(node.left)
else:
node = stack.pop()
res.append(node.val)
return res