返回
树的深度优先遍历+树的重心详解
后端
2023-09-14 12:09:05
深度优先遍历
深度优先遍历(DFS)是一种遍历树或图的算法。它通过递归或栈的方式,沿着树或图的深度遍历其节点。DFS 的基本思想是:从一个节点出发,访问该节点的所有子节点,然后依次访问这些子节点的子节点,依此类推,直到所有节点都被访问。
DFS 的优点是:
- 对于树来说,DFS 的时间复杂度为 O(V + E),其中 V 是树中的节点数,E 是树中的边数。
- DFS 可以很容易地找到树中的路径。
- DFS 可以很容易地找到树中的环。
DFS 的缺点是:
- DFS 可能会访问到重复的节点。
- DFS 可能会导致栈溢出。
树的重心
树的重心是指一棵树中一个或多个具有最小总距离和的节点。换句话说,树的重心是树中到所有其他节点的距离之和最小的节点。
树的重心可以用来解决许多问题,例如:
- 在树中寻找一个位置,使得从该位置到所有其他节点的距离之和最小。
- 在树中寻找一个位置,使得从该位置到所有其他节点的距离之和最大。
- 在树中寻找一个位置,使得从该位置到所有其他节点的距离之和平均最小。
算法实现
我们可以使用 DFS 来计算树的重心。
def find_centroid(tree, root):
"""
Finds the centroid of a tree.
Args:
tree: A tree represented as a list of lists of integers.
root: The root node of the tree.
Returns:
The centroid of the tree.
"""
# Initialize the visited array.
visited = [False] * len(tree)
# Initialize the size array.
size = [0] * len(tree)
# Initialize the distance array.
distance = [0] * len(tree)
# Initialize the centroid array.
centroid = [-1] * len(tree)
# Find the size of the tree.
dfs_size(tree, root, visited, size)
# Find the distance from each node to the root.
dfs_distance(tree, root, visited, distance)
# Find the centroid of the tree.
find_centroid_dfs(tree, root, visited, size, distance, centroid)
# Return the centroid of the tree.
return centroid
def dfs_size(tree, root, visited, size):
"""
Finds the size of a tree.
Args:
tree: A tree represented as a list of lists of integers.
root: The root node of the tree.
visited: A list of booleans indicating whether each node has been visited.
size: A list of integers storing the size of each node.
"""
# Mark the current node as visited.
visited[root] = True
# Initialize the size of the current node.
size[root] = 1
# Recursively visit the children of the current node.
for child in tree[root]:
if not visited[child]:
dfs_size(tree, child, visited, size)
# Add the size of the child to the size of the current node.
size[root] += size[child]
def dfs_distance(tree, root, visited, distance):
"""
Finds the distance from each node to the root.
Args:
tree: A tree represented as a list of lists of integers.
root: The root node of the tree.
visited: A list of booleans indicating whether each node has been visited.
distance: A list of integers storing the distance from each node to the root.
"""
# Mark the current node as visited.
visited[root] = True
# Initialize the distance from the current node to the root.
distance[root] = 0
# Recursively visit the children of the current node.
for child in tree[root]:
if not visited[child]:
dfs_distance(tree, child, visited, distance)
# Add the distance from the child to the root to the distance from the current node to the root.
distance[root] += distance[child] + 1
def find_centroid_dfs(tree, root, visited, size, distance, centroid):
"""
Finds the centroid of a tree.
Args:
tree: A tree represented as a list of lists of integers.
root: The root node of the tree.
visited: A list of booleans indicating whether each node has been visited.
size: A list of integers storing the size of each node.
distance: A list of integers storing the distance from each node to the root.
centroid: A list of integers storing the centroid of the tree.
"""
# Mark the current node as visited.
visited[root] = True
# Check if the current node is a centroid.
if size[root] * 2 <= len(tree):
centroid[root] = True
# Recursively visit the children of the current node.
for child in tree[root]:
if not visited[child]:
find_centroid_dfs(tree, child, visited, size, distance, centroid)
# Check if the child is a centroid.
if centroid[child]:
centroid[root] = False
# Check if the current node is the centroid.
if centroid[root]:
for child in tree[root]:
if not visited[child]:
dfs_distance(tree, child, visited, distance)
# Check if the child is a centroid.
if distance[child] * 2 >= len(tree):
centroid[root] = False
参考文献
结语
深度优先遍历和树的重心是两个重要的图论概念。它们可以用来解决许多问题,例如:找到树中到所有其他节点的距离之和最小的节点、找到树中到所有其他节点的距离之和最大的节点、找到树中到所有其他节点的距离之和平均最小的节点等。