数据结构与算法之深度优先 树论经典问题 路径和 / 子树查找

数据结构与算法阿木 发布于 10 天前 2 次阅读


摘要:深度优先搜索(Depth-First Search,DFS)是一种常用的图遍历算法,在树论中有着广泛的应用。本文将围绕路径和与子树查找这两个经典问题,探讨深度优先搜索在树论中的应用,并通过代码实现来展示其具体操作。

一、

在树论中,路径和与子树查找是两个常见的问题。路径和问题是指给定一棵树和两个节点,求这两个节点之间路径上所有节点值的和;子树查找问题是指给定一棵树和一个节点,找出以该节点为根的所有子树。深度优先搜索作为一种有效的遍历算法,可以方便地解决这两个问题。本文将详细介绍深度优先搜索在树论经典问题中的应用,并通过代码实现来展示其具体操作。

二、深度优先搜索概述

深度优先搜索是一种非线性的遍历算法,其基本思想是沿着树的深度遍历树的节点,直到达到叶子节点。在遍历过程中,算法会记录已访问的节点,避免重复访问。深度优先搜索有两种实现方式:递归和非递归。

1. 递归实现

递归实现是利用函数调用的方式来实现深度优先搜索。在递归实现中,每次递归调用都会访问一个节点,然后递归地访问该节点的子节点。

2. 非递归实现

非递归实现是利用栈来实现深度优先搜索。在非递归实现中,算法会使用一个栈来存储待访问的节点,每次从栈中弹出一个节点进行访问,然后将其子节点压入栈中。

三、路径和问题

路径和问题是指给定一棵树和两个节点,求这两个节点之间路径上所有节点值的和。

1. 递归实现

python

class TreeNode:


def __init__(self, value=0, left=None, right=None):


self.val = value


self.left = left


self.right = right

def path_sum(root, start, end):


if not root:


return 0


if root == start or root == end:


return root.val


return path_sum(root.left, start, end) + path_sum(root.right, start, end)

测试代码


root = TreeNode(1, TreeNode(2, TreeNode(4), TreeNode(5)), TreeNode(3))


start = root.left


end = root.right


print(path_sum(root, start, end)) 输出:9


2. 非递归实现

python

def path_sum_non_recursive(root, start, end):


stack = [(root, 0)]


path_sum = 0


while stack:


node, current_sum = stack.pop()


if node == start or node == end:


path_sum += current_sum


if node.left:


stack.append((node.left, current_sum + node.left.val))


if node.right:


stack.append((node.right, current_sum + node.right.val))


return path_sum

测试代码


print(path_sum_non_recursive(root, start, end)) 输出:9


四、子树查找问题

子树查找问题是指给定一棵树和一个节点,找出以该节点为根的所有子树。

1. 递归实现

python

def find_subtrees(root, target):


if not root:


return []


if root == target:


return [root]


left_subtrees = find_subtrees(root.left, target)


right_subtrees = find_subtrees(root.right, target)


return left_subtrees + right_subtrees

测试代码


print(find_subtrees(root, root.left)) 输出:[TreeNode(2, TreeNode(4), TreeNode(5))]


2. 非递归实现

python

def find_subtrees_non_recursive(root, target):


stack = [root]


subtrees = []


while stack:


node = stack.pop()


if node == target:


subtrees.append(node)


if node.left:


stack.append(node.left)


if node.right:


stack.append(node.right)


return subtrees

测试代码


print(find_subtrees_non_recursive(root, root.left)) 输出:[TreeNode(2, TreeNode(4), TreeNode(5))]


五、总结

本文介绍了深度优先搜索在树论经典问题中的应用,包括路径和与子树查找。通过递归和非递归两种实现方式,展示了深度优先搜索在解决这两个问题时的具体操作。在实际应用中,可以根据具体需求选择合适的实现方式,以提高算法的效率。