Skip to content

Commit e1552a9

Browse files
committed
修复和优化语句表述
1 parent ac4e899 commit e1552a9

File tree

1 file changed

+37
-42
lines changed

1 file changed

+37
-42
lines changed

docs/06_graph/06_07_graph_shortest_path_01.md

Lines changed: 37 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -128,54 +128,61 @@ for i in range(1, n + 1):
128128
### 3.2 堆优化 Dijkstra 算法实现步骤
129129

130130
1. 初始化距离数组,源点距离设为 $0$,其余节点设为无穷大。
131-
2. 创建优先队列, $(0, source)$ 入队。
131+
2. 创建优先队列,将源节点及其距离 $(0, source)$ 入队。
132132
3. 当优先队列非空时,重复以下操作:
133133
- 弹出队首(距离最小)节点;
134-
- 若该节点的距离已大于当前最短距离,跳过;
134+
- 如果该节点的距离已大于当前最短距离,跳过;
135135
- 否则,遍历其所有邻居,尝试松弛:
136-
- 若通过当前节点到邻居的距离更短,则更新距离并将新距离入队。
136+
- 如果通过当前节点到邻居的距离更短,则更新距离并将新距离入队。
137137
4. 队列为空时结束,返回所有节点的最短距离数组。
138138

139-
### 3.3 堆优化的 Dijkstra 算法实现代码
139+
### 3.3 堆优化 Dijkstra 算法实现代码
140140

141141
```python
142142
import heapq
143143

144144
class Solution:
145145
def dijkstra(self, graph, n, source):
146-
# 初始化距离数组
147-
dist = [float('inf') for _ in range(n + 1)]
148-
dist[source] = 0
149-
150-
# 创建优先队列,存储 (距离, 节点) 的元组
146+
"""
147+
堆优化 Dijkstra 算法,计算单源最短路径
148+
:param graph: 邻接表,graph[u] = {v: w, ...}
149+
:param n: 节点总数(节点编号从 1 到 n)
150+
:param source: 源点编号
151+
:return: dist[i] 表示源点到 i 的最短距离
152+
"""
153+
# 距离数组,初始化为无穷大
154+
dist = [float('inf')] * (n + 1)
155+
dist[source] = 0 # 源点到自身距离为 0
156+
157+
# 小根堆,存储 (距离, 节点) 元组
151158
priority_queue = [(0, source)]
152-
159+
153160
while priority_queue:
154161
current_distance, current_node = heapq.heappop(priority_queue)
155-
156-
# 如果当前距离大于已知的最短距离,跳过
162+
# 如果弹出的节点距离不是最短的,说明已被更新,跳过
157163
if current_distance > dist[current_node]:
158164
continue
159-
160-
# 遍历当前节点的所有相邻节点
161-
for neighbor, weight in graph[current_node].items():
162-
distance = current_distance + weight
163-
if distance < dist[neighbor]:
164-
dist[neighbor] = distance
165-
heapq.heappush(priority_queue, (distance, neighbor))
166-
165+
166+
# 遍历当前节点的所有邻居
167+
for neighbor, weight in graph.get(current_node, {}).items():
168+
new_distance = current_distance + weight
169+
# 如果找到更短路径,则更新并入堆
170+
if new_distance < dist[neighbor]:
171+
dist[neighbor] = new_distance
172+
heapq.heappush(priority_queue, (new_distance, neighbor))
173+
167174
return dist
168175

169176
# 使用示例
170-
# 创建一个有向图,使用邻接表表示
177+
# 构建一个有向图,邻接表表示
171178
graph = {
172179
1: {2: 2, 3: 4},
173180
2: {3: 1, 4: 7},
174181
3: {4: 3},
175182
4: {}
176183
}
177-
n = 4 # 图中节点数量
178-
source = 1 # 源节点
184+
n = 4 # 节点数量
185+
source = 1 # 源点编号
179186

180187
dist = Solution().dijkstra(graph, n, source)
181188
print("从节点", source, "到其他节点的最短距离:")
@@ -186,27 +193,15 @@ for i in range(1, n + 1):
186193
print(f"到节点 {i} 的距离:{dist[i]}")
187194
```
188195

189-
代码解释:
190-
191-
1. `graph` 是一个字典,表示图的邻接表。例如,`graph[1] = {2: 3, 3: 4}` 表示从节点 1 到节点 2 的边权重为 3,到节点 3 的边权重为 4。
192-
2. `n` 是图中顶点的数量。
193-
3. `source` 是源节点的编号。
194-
4. `dist` 数组存储源点到各个节点的最短距离。
195-
5. `priority_queue` 是一个优先队列,用来选择当前距离源点最近的节点。队列中的元素是 (距离, 节点) 的元组。
196-
6. 主循环中,每次从队列中取出距离最小的节点。如果该节点的距离已经被更新过,跳过。
197-
7. 对于当前节点的每一个邻居,计算通过当前节点到达邻居的距离。如果这个距离比已知的更短,更新距离并将邻居加入队列。
198-
8. 最终,`dist` 数组中存储的就是源点到所有节点的最短距离。
199-
200-
### 3.4 堆优化的 Dijkstra 算法复杂度分析
196+
### 3.4 堆优化 Dijkstra 算法复杂度分析
201197

202-
- **时间复杂度**:$O((V + E) \log V)$
203-
- 每个节点最多被加入优先队列一次,每次操作的时间复杂度为 $O(\log V)$
204-
- 每条边最多被处理一次,每次处理的时间复杂度为 $O(\log V)$
205-
- 因此总时间复杂度为 $O((V + E) \log V)$
198+
- **时间复杂度**:$O((V + E) \log V)$
199+
- 堆优化 Dijkstra 算法中,每个节点最多会被弹出优先队列一次,每次弹出操作的复杂度为 $O(\log V)$
200+
- 每条边在松弛操作时最多会导致一次入堆,入堆操作的复杂度同样为 $O(\log V)$
201+
- 因此,总体时间复杂度为 $O((V + E) \log V)$,其中 $V$ 为节点数,$E$ 为边数。
206202

207-
- **空间复杂度**:$O(V)$
208-
- 需要存储距离数组,大小为 $O(V)$。
209-
- 优先队列在最坏情况下可能存储所有节点,大小为 $O(V)$。
203+
- **空间复杂度**:$O(V)$。
204+
- 主要空间消耗在距离数组和优先队列,二者最坏情况下均为 $O(V)$ 级别。
210205

211206
## 练习题目
212207

0 commit comments

Comments
 (0)