数据结构与算法之 leetcode 图论最短路径算法 Dijkstra 实现

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


图论最短路径算法:Dijkstra 算法实现

在图论中,最短路径问题是一个经典且重要的课题。它广泛应用于网络通信、路径规划、物流运输等领域。Dijkstra 算法是一种用于解决单源最短路径问题的有效算法。本文将围绕 Dijkstra 算法,从基本概念、算法原理、实现方法以及优化策略等方面进行详细阐述。

基本概念

图是由节点(也称为顶点)和边组成的集合。节点表示实体,边表示实体之间的关系。图分为有向图和无向图,以及加权图和无权图。

路径

路径是图中节点序列,表示从起点到终点的连接。路径的长度是路径上所有边的权重之和。

最短路径

最短路径是从起点到终点的路径中,路径长度最短的路径。

单源最短路径

单源最短路径问题是指从图中某个节点出发,找到到达其他所有节点的最短路径。

Dijkstra 算法原理

Dijkstra 算法是一种基于贪心策略的单源最短路径算法。其基本思想是:从起点出发,逐步扩展到相邻节点,每次扩展都选择当前未访问节点中距离起点最近的节点,直到所有节点都被访问过。

算法步骤

1. 初始化:将起点加入已访问集合,其余节点加入未访问集合,并将起点到所有节点的距离初始化为无穷大,起点到自身的距离为0。

2. 循环遍历未访问集合:

a. 从未访问集合中选取距离起点最近的节点,将其加入已访问集合。

b. 更新未访问集合中所有相邻节点的距离:如果通过当前节点到达相邻节点的距离小于已记录的距离,则更新该距离。

3. 当未访问集合为空时,算法结束。

Dijkstra 算法实现

以下是用 Python 实现的 Dijkstra 算法:

python

def dijkstra(graph, start):


初始化距离表


distances = {node: float('inf') for node in graph}


distances[start] = 0


初始化未访问集合


unvisited = set(graph.keys())


初始化前驱节点表


predecessors = {node: None for node in graph}

while unvisited:


选择距离起点最近的节点


current_node = min(unvisited, key=lambda node: distances[node])


将当前节点加入已访问集合


unvisited.remove(current_node)


更新相邻节点的距离


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


if neighbor in unvisited:


new_distance = distances[current_node] + weight


if new_distance < distances[neighbor]:


distances[neighbor] = new_distance


predecessors[neighbor] = current_node

return distances, predecessors

示例


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}


}


distances, predecessors = dijkstra(graph, 'A')


print("Distance:", distances)


print("Predecessors:", predecessors)


Dijkstra 算法优化策略

1. 优先队列:使用优先队列(如二叉堆)来存储未访问节点,以实现更快的查找和更新操作。

2. 动态规划:将 Dijkstra 算法与动态规划相结合,解决具有重复子问题的最短路径问题。

3. A 算法:结合启发式搜索和 Dijkstra 算法,提高算法的搜索效率。

总结

Dijkstra 算法是一种有效的单源最短路径算法,具有简单、易实现的特点。在实际应用中,可以根据具体问题选择合适的优化策略,提高算法的效率。本文对 Dijkstra 算法进行了详细阐述,包括基本概念、原理、实现方法以及优化策略,希望能对读者有所帮助。