1. 项目概述
Tree Distances I 是一个关于树形结构中节点距离计算的经典算法问题。作为一名算法工程师,我经常需要在各种场景下处理树形结构数据,而计算节点之间的距离是最基础也是最重要的操作之一。这个问题看似简单,但其中蕴含着许多值得深入探讨的算法思想和优化技巧。
在实际项目中,无论是社交网络中的好友关系分析、文件系统的目录结构遍历,还是组织架构中的层级关系处理,都需要高效地计算树节点之间的距离。本文将分享我在解决这类问题时积累的经验和技巧,包括多种算法的实现细节和性能对比。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心算法解析
2.1 问题定义与基础解法
树距离问题可以形式化定义为:给定一棵有n个节点的树,要求计算所有节点对(i,j)之间的距离d(i,j)。这里的距离指的是两个节点之间最短路径上的边数。
最直观的解法是使用BFS(广度优先搜索):
python复制from collections import deque
def tree_distances_bfs(tree):
n = len(tree)
distances = [[0]*n for _ in range(n)]
for u in range(n):
visited = [False]*n
q = deque([(u, 0)])
visited[u] = True
while q:
node, dist = q.popleft()
for v in tree[node]:
if not visited[v]:
distances[u][v] = dist + 1
visited[v] = True
q.append((v, dist + 1))
return distances
这个算法的时间复杂度是O(n²),因为对每个节点都要做一次BFS遍历。对于大规模树结构来说,这样的复杂度显然不够理想。
2.2 优化思路与算法选择
经过实践和研究,我发现以下几种优化方法特别有效:
- 动态规划法:利用树结构的递归特性,通过后序遍历计算子树信息
- LCA(最低公共祖先)法:先预处理出每个节点的祖先信息,然后利用公式d(u,v)=depth[u]+depth[v]-2*depth[lca(u,v)]
- 重链剖分:将树分解为多条链,优化查询效率
其中,LCA法在实际应用中表现最为均衡。下面是基于二进制提升的LCA实现:
python复制class TreeDistanceLCA:
def __init__(self, tree):
self.n = len(tree)
self.log = 0
while (1 << self.log) < self.n:
self.log += 1
self.up = [[-1]*self.n for _ in range(self.log)]
self.depth = [0]*self.n
# BFS初始化
q = deque([0])
self.up[0][0] = -1
while q:
u = q.popleft()
for v in tree[u]:
if self.up[0][v] == -1 and v != 0:
self.up[0][v] = u
self.depth[v] = self.depth[u] + 1
q.append(v)
# 二进制提升预处理
for k in range(1, self.log):
for v in range(self.n):
if self.up[k-1][v] != -1:
self.up[k][v] = self.up[k-1][self.
