树与递归
前言
树结构在很多操作中都会用到递归,其中一些常见的树操作包括:
- 遍历(Traversal):树的前序遍历、中序遍历、后序遍历以及层序遍历都可以通过递归来实现。递归是一种自然而然地处理树结构的方式,因为树的结构本身就天然地递归定义了。
- 搜索:在树中进行搜索操作时,比如查找特定节点或者特定值,通常也可以使用递归。例如,在二叉搜索树(BST)中查找某个节点的操作就可以通过递归来实现。
- 插入和删除:向树中插入新节点或者删除指定节点时,递归也是一个常见的实现方式。特别是在平衡二叉搜索树(AVL 树、红黑树等)中,插入和删除操作通常会涉及到树的旋转,递归能够很好地处理这些情况。
- 求解路径/路径和:有些问题需要求解树中从根节点到叶子节点的路径,或者计算路径上节点值的和,这类问题也常常使用递归来处理。
- 构建树:有时候需要根据给定的数据构建一棵树,比如从先序遍历和中序遍历结果构建一棵二叉树。递归在这种场景下也非常实用。
最大深度和前中后序遍历
class TreeNode:
def __init__(self, value=0, left=None, right=None):
self.value = value
self.left = left
self.right = right
def max_depth(root):
if root is None:
return 0
else:
left_depth = max_depth(root.left)
right_depth = max_depth(root.right)
shendu = max(left_depth, right_depth) + 1
return shendu
def inorder_traversal(node):
if node is not None:
inorder_traversal(node.left)
value = node.value
print(value) # 可以根据需求调整输出位置
inorder_traversal(node.right)
def preorder_traversal(node):
if node is not None:
print(node.value) # 可以根据需求调整输出位置
preorder_traversal(node.left)
preorder_traversal(node.right)
def postorder_traversal(node):
if node is not None:
postorder_traversal(node.left)
postorder_traversal(node.right)
print(node.value) # 可以根据需求调整输出位置
二叉搜索树
def insert_node(root, value):
if root is None:
return TreeNode(value)
if value < root.value:
root.left = insert_node(root.left, value)
else:
root.right = insert_node(root.right, value)
return root
这段代码是一个递归函数,用于向二叉搜索树中插入新节点。让我来解释一下这段代码的逻辑:
- 如果当前节点
root
为空(即二叉树为空或者递归到了叶子节点的左/右子节点),则说明可以将新节点作为当前位置的节点,直接返回一个包含该值的新节点TreeNode(value)
。 - 如果当前节点
root
不为空,则比较要插入的值value
和当前节点的值root.value
的大小关系:- 如果
value
小于root.value
,则将新节点插入到当前节点的左子树中。递归调用insert_node(root.left, value)
,并将返回的新左子树根节点赋给root.left
。 - 如果
value
大于等于root.value
,则将新节点插入到当前节点的右子树中。递归调用insert_node(root.right, value)
,并将返回的新右子树根节点赋给root.right
。
- 如果
- 最后,返回当前节点
root
,表示完成插入操作后的二叉搜索树的根节点。
# 构建一个 BST 示例
def build_bst(values):
root = None
for value in values:
root = insert_node(root, value)
return root
def search_bst(root,target):
if root is None:
print("树中不存在该结点")
return None
if root.value == target:
print("在树中找到了结点")
return root
if target < root.value:
return search_bst(root.left,target)
else:
return search_bst(root.right,target)
values = [5, 3, 7, 1, 4, 6, 8]
# 构建二叉搜索树
bst_root = build_bst(values)
二叉搜索树中有重复值
def search_all_matches(root, target, matches):
if root is None:
return
if root.value == target:
matches.append(root)
search_all_matches(root.left, target, matches)
search_all_matches(root.right, target, matches)
# 示例用法
root = TreeNode(5)
root.left = TreeNode(3)
root.right = TreeNode(8)
root.left.left = TreeNode(3)
root.left.right = TreeNode(5)
root.right.left = TreeNode(7)
root.right.right = TreeNode(8)
matches = []
search_all_matches(root, 5, matches)
for node in matches:
print(node.value)
要搜索并找到二叉搜索树中所有匹配的重复值,你可以稍微修改搜索函数来实现这个功能。一种方法是在找到目标值后,不立即返回,而是继续搜索当前节点的左子树和右子树,以找到所有匹配的节点。