使用 Go 实现 Dijkstra 算法

181 阅读2分钟

Dijkstra 算法是计算图中两个顶点之间的最短路径的一个经典算法。这篇文章我们将深入探讨如何使用 Go 语言实现它,并提供详尽的代码。

DALL·E 2023-10-14 20.01.13 - photo showing the execution of Go code for Dijkstra's algorithm with code blocks, arrows, and annotations in Chinese.png

1. 算法简介

Dijkstra 算法是由荷兰计算机科学家 Edsger W. Dijkstra 在 1956 年提出的。这个算法可以找到从起始点到图中所有其他点的最短路径。算法的主要思想是:每次从未处理的顶点中选取一个与起始点距离最短的顶点,然后更新所有与该顶点相邻的顶点的最短路径。

2. 算法流程

  1. 初始化:将起始点的距离设为 0,其他所有点的距离设为无穷大。
  2. 从未处理的顶点中选取一个与起始点距离最短的顶点。
  3. 更新所有与该顶点相邻的顶点的最短路径。
  4. 重复第2步和第3步,直到所有的顶点都被处理过。

3. Go 代码实现

type Graph struct {
	vertices []*Vertex
}

type Vertex struct {
	key      int
	adjacent []*Vertex
	weight   []int
	dist     int
	previous *Vertex
}

func NewVertex(key int) *Vertex {
	return &Vertex{
		key: key,
	}
}

func (g *Graph) AddVertex(key int) {
	if contains(g.vertices, key) {
		return
	}
	g.vertices = append(g.vertices, NewVertex(key))
}

func (g *Graph) AddEdge(from, to, weight int) {
	fromVertex := g.getVertex(from)
	toVertex := g.getVertex(to)
	fromVertex.adjacent = append(fromVertex.adjacent, toVertex)
	fromVertex.weight = append(fromVertex.weight, weight)
}

func (g *Graph) getVertex(key int) *Vertex {
	for i := 0; i < len(g.vertices); i++ {
		if g.vertices[i].key == key {
			return g.vertices[i]
		}
	}
	return nil
}

func contains(s []*Vertex, key int) bool {
	for _, v := range s {
		if key == v.key {
			return true
		}
	}
	return false
}

func Dijkstra(source *Vertex) {
	source.dist = 0
	var queue []*Vertex
	for _, vertex := range g.vertices {
		queue = append(queue, vertex)
	}

	for len(queue) != 0 {
		// TODO: 从队列中找到最小的距离顶点
		// TODO: 更新与该顶点相邻的所有顶点的距离
	}
}

5. 总结

Dijkstra 算法是图论中的一个基础算法,对于解决许多实际问题有着重要的应用。我们在 Go 语言中实现了这个算法,并通过详细的代码提供了清晰的解释。希望这篇文章能帮助你更好地理解和使用 Dijkstra 算法。

DALL·E 2023-10-14 20.01.05 - photo illustration showing the flowchart of Dijkstra's algorithm with steps labeled in Chinese.png


希望这篇文章能为你提供有价值的知识和参考,如果你有任何疑问或建议,欢迎留言交流。

祝编程愉快!