Go语言数据结构和算法(三十二)最短路径

11 阅读3分钟

最短路径是在图中找到两个顶点之间的路径以使其组成的边的权重之和最小化的问

题.特性如下.

最短路径的所有子路径也必须是最短路径.

如果存在两个节点A和B之间的最短路径长度.那么贪婪的选择B到C之间长度最小的

边给出A和C之间的最短路径长度.

1.Dijkstra算法:

找到图中任意两个节点之间的最短路径的算法.它与最小生成树不同.因为两个节点之间的最短距离可能不包括图中的所有顶点.

2.步骤:

创建距离图.存储从源节点到每个节点的距离.将所有值初始化为无穷大.

创建顶点映射.将顶点标记为已访问和未访问.

对于源节点.标记距离为0.(权重应该为非负数).

将源节点插入队列.

将节点从队列中取出并访问所有未访问的邻居.计算通过当前节点的指定距离.如果暂定距离小于当前分配距离.则更新距离并分配较小的距离.将距离最小的顶点添加到优先级队列中.

要在步骤五中获取最短路径.请存储先前节点名称.重复此操作.直到优先级队列为空.

3.使用场景:

计算机网络中的路由协议:

Dijkstra算法在网络协议中用于查找网络中两个节点之间的最短路径.

优化交通规划:

Dijkstra算法可用于优化交通路线.如在道路上寻找两个城市之间的最短路径.

游戏开发:

在游戏开发中用于模拟AI角色的移动.如寻找游戏地图上两点之间的最短路径.

4.实现:

4.1方法:

package data

import "math"

func DijkStrat(graph [][]int, source int, destination int, n int) int {
    //初始化变量.
    dist := make([]int, n)
    visited := make([]bool, n)
    var MAX = math.MaxInt32
    for i := 0; i < n; i++ {
       dist[i] = MAX
       visited[i] = false
    }
    dist[source] = 0
    //寻找最短路径.
    for i := 0; i < n-1; i++ {
       minIndex := findMinVertexDijk(dist, visited, n)
       visited[minIndex] = true
       for j := 0; j < n; j++ {
          if !visited[j] && graph[minIndex][j] != 0 &&
             dist[minIndex] != MAX &&
             dist[minIndex]+graph[minIndex][j] < dist[j] {
             dist[j] = dist[minIndex] + graph[minIndex][j]
          }
       }
    }
    return dist[destination]
}

func findMinVertexDijk(dist []int, visited []bool, n int) int {
    var MAX = math.MaxInt32
    min := MAX
    minIndex := -1
    for i := 0; i < n; i++ {
       if visited[i] == false && dist[i] <= min {
          min = dist[i]
          minIndex = i
       }
    }
    return minIndex
}
```
```

#### ***4.2main方法:***

```
func main() {
	graph := [][]int{{0, 4, 0, 0},
		{4, 0, 8, 0},
		{0, 8, 0, 7},
		{0, 0, 7, 0}}
	dijk := data.DijkStrat(graph, 0, 1, 3)
	fmt.Println(dijk)
}
```
## 5.实战:

### 5.1方法:

```
func Trap(height []int) int {
	res := 0
	peakIndex := 0
	for i := 0; i < len(height); i++ {
		if height[i] > height[peakIndex] {
			peakIndex = i
		}
	}
	left := 0
	for i := 0; i < peakIndex; i++ {
		if height[i] > left {
			left = height[i]
		} else {
			res += left - height[i]
		}
	}
	right := 0
	for i := len(height) - 1; i > peakIndex; i-- {
		if height[i] > right {
			right = height[i]
		} else {
			res += right - height[i]
		}
	}
	return res
}
```

### 5.2main方法:

```
func main() {
	arr := []int{1, 3, 2, 4, 1, 3, 1, 4, 5, 2, 2, 1, 4, 2, 2}
	trap := data.Trap(arr)
	fmt.Println(trap)
}
```


不知天上宫阙.今夕是何年.

如果大家喜欢我的分享的话.可以关注我的微信公众号

念何架构之路