数据结构与算法之算法 图论算法面试高频 最短路径变形

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


图论算法面试高频:最短路径变形问题解析与代码实现

在图论中,最短路径问题是一个经典且重要的课题。它广泛应用于网络设计、路径规划、物流运输等领域。在面试中,最短路径问题及其变形往往是考察算法和数据结构能力的重点。本文将围绕最短路径变形问题,探讨几种常见的算法,并给出相应的代码实现。

1. Dijkstra算法

Dijkstra算法是一种用于在加权图中找到单源最短路径的算法。它适用于非负权重的图。

1.1 算法原理

Dijkstra算法的基本思想是维护一个集合S,其中包含已确定最短路径的顶点。算法开始时,S为空,然后逐步扩大S,直到包含所有顶点。

1. 初始化:将源点加入S,其余顶点的距离设为无穷大,记录源点到其余顶点的最短路径。

2. 循环:从集合S中选取距离最小的顶点u,将其加入S。

3. 更新:对于集合S中的每个顶点v,如果存在从u到v的边,并且通过u到v的距离小于当前记录的距离,则更新v的距离和最短路径。

1.2 代码实现

python

import heapq

def dijkstra(graph, start):


distances = {vertex: float('infinity') for vertex in graph}


distances[start] = 0


priority_queue = [(0, start)]



while priority_queue:


current_distance, current_vertex = heapq.heappop(priority_queue)



if current_distance > distances[current_vertex]:


continue



for neighbor, weight in graph[current_vertex].items():


distance = current_distance + weight



if distance < distances[neighbor]:


distances[neighbor] = distance


heapq.heappush(priority_queue, (distance, neighbor))



return distances

示例图


graph = {


'A': {'B': 1, 'C': 4},


'B': {'A': 1, 'C': 2, 'D': 5},


'C': {'A': 4, 'B': 2, 'D': 1},


'D': {'B': 5, 'C': 1}


}

测试


print(dijkstra(graph, 'A'))


2. Bellman-Ford算法

Bellman-Ford算法是一种用于在加权图中找到单源最短路径的算法。它适用于有负权边的图。

2.1 算法原理

Bellman-Ford算法的基本思想是逐步放松边,即对于每一条边(u, v),如果存在从源点到u的路径,并且通过(u, v)的距离小于当前记录的距离,则更新v的距离。

1. 初始化:将源点的距离设为0,其余顶点的距离设为无穷大。

2. 循环:对于图中的每一条边,执行放松操作。

3. 检查负权重循环:如果存在从源点到某个顶点的路径,并且该路径的权重小于0,则图中存在负权重循环。

2.2 代码实现

python

def bellman_ford(graph, start):


distances = {vertex: float('infinity') for vertex in graph}


distances[start] = 0



for _ in range(len(graph) - 1):


for u in graph:


for v, weight in graph[u].items():


if distances[u] + weight < distances[v]:


distances[v] = distances[u] + weight



检查负权重循环


for u in graph:


for v, weight in graph[u].items():


if distances[u] + weight < distances[v]:


raise ValueError("Graph contains a negative weight cycle")



return distances

测试


print(bellman_ford(graph, 'A'))


3. Floyd-Warshall算法

Floyd-Warshall算法是一种用于在加权图中找到所有顶点对之间的最短路径的算法。

3.1 算法原理

Floyd-Warshall算法的基本思想是逐步更新路径,即对于每一条边(u, v),如果存在从源点到u的路径,并且通过(u, v)的距离小于当前记录的距离,则更新v的距离。

1. 初始化:将所有顶点的距离设为无穷大,对角线上的距离设为0。

2. 循环:对于每个顶点k,执行以下操作:

- 对于每个顶点i,如果存在从源点到i的路径,并且通过(i, k)的距离小于当前记录的距离,则更新i到k的距离。

- 对于每个顶点j,如果存在从源点到k的路径,并且通过(k, j)的距离小于当前记录的距离,则更新i到j的距离。

3.2 代码实现

python

def floyd_warshall(graph):


distances = [[float('infinity')] len(graph) for _ in range(len(graph))]



for i in range(len(graph)):


distances[i][i] = 0



for u in range(len(graph)):


for v, weight in graph[u].items():


distances[u][v] = weight



for k in range(len(graph)):


for i in range(len(graph)):


for j in range(len(graph)):


if distances[i][k] + distances[k][j] < distances[i][j]:


distances[i][j] = distances[i][k] + distances[k][j]



return distances

测试


print(floyd_warshall(graph))


4. 总结

本文介绍了三种最短路径变形问题的算法:Dijkstra算法、Bellman-Ford算法和Floyd-Warshall算法。这些算法在面试中经常出现,掌握它们对于提高算法和数据结构能力具有重要意义。在实际应用中,根据具体问题选择合适的算法,可以有效地解决最短路径问题。