迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959
年提出的,所以又叫狄克斯特拉算法。是从一个顶点到其他各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特色是以起始点为中心向外层层扩展,直到扩展到终点为止
ps: Dijkstra算法是一种贪心算法javascript
以上图为例
咱们要求出顶点A到其他各顶点间的最短路径
首先咱们先定义出上图的邻接矩阵java
let graph = [[0,2,4,0,0,0], [0,0,1,4,2,0], [0,0,0,0,3,0], [0,0,0,0,0,2], [0,0,0,3,0,2], [0,0,0,0,0,0]]
ps: 邻接矩阵的意思是: 用一个二数组表示个顶点间的关系,来肯定各顶点间的关系,由于图为有向图,因此上图的邻接矩阵如上算法
先放出Dijkstra算法的所有代码再来结合慢慢解析数组
let index = 'ABCDEF' let INF = Number.MAX_SAFE_INTEGER //1 function dijkstra(src) { let dist = [],//2 visited = [],//3 length = graph.length//4 for (let i = 0; i < length; i++) { dist[i] = INF visited[i] = false }//5 dist[src] = 0 for (let i = 0; i < length - 1; i++) { let u = minDistance(dist, visited) visited[u] = true for (let v = 0; v < length; v++) { if (!visited[v] && dist[u] !== INF && graph[u][v] > 0 && dist[u] + graph[u][v] < dist[v]) { dist[v] = dist[u] + graph[u][v] } } } return dist } function minDistance(dist, visited) { let min = INF, minIndex = -1 for (let v = 0; v < dist.length; v++) { if (visited[v] === false && dist[v] <= min) { min = dist[v] minIndex = v } } return minIndex }
1.初始化数据
定义 dist 数组来储存当前A顶点到其它各个顶点间的距离
定义 visited 数组来储存ABCDEF顶点是否被访问过,以避免重复访问,造成环
定义 length 来储存全部顶点的数量
定义 INF 为javascript的最大整数 Number.MAX_SAFE_INTEGER函数
for (let i = 0; i < length; i++) { dist[i] = INF visited[i] = false }//5 dist[src] = 0
初始化dist visted 数组,把全部顶点距离初始化为无限大,全部顶点定义为为访问
把顶点A到本身的距离初始化为0
2.过程解析spa
//顶点探索函数 for (let i = 0; i < length - 1; i++) { let u = minDistance(dist, visited) visited[u] = true for (let v = 0; v < length; v++) { if (!visited[v] && dist[u] !== INF && graph[u][v] > 0 && dist[u] + graph[u][v] < dist[v]) { dist[v] = dist[u] + graph[u][v] } } }
//寻找最短路径函数 function minDistance(dist, visited) { let min = INF, minIndex = -1 for (let v = 0; v < dist.length; v++) { if (visited[v] === false && dist[v] <= min) { min = dist[v] minIndex = v } } return minIndex }
具体探索逻辑以下code
第一次循环
找到最短顶点A
遍历A到其余顶点的距离,若是和其余顶点有直接联系,则判断A到其余顶点的距离,是不是A目前到X顶点的距离 + X到新顶点的距离 < A新顶点的距离
若是小于,则更新到该顶点最短距离blog
第一次循环完后相应输出值
发现A
遍历发现A -> B为2 A->C为4 均小于无穷大,因此更新A点到B,C的最短距离ip
visited -> [ true, false, false, false, false, false ] dist -> [ 0, 2, 4, 9007199254740991, 9007199254740991, 9007199254740991 ]
第二次循环
找到最短的那个边,除A之外 因此探索B点
遍历发现 B->C,B->E, B->D分别为1,2,4
则
A-C距离为A-B + B-C = 3小于直接到C的距离4 因此更新A-C最短距离it
visited -> [ true, true, false, false, false, false ] dist -> [ 0, 2, 3, 6, 4, 9007199254740991 ]
剩下三次探索输出为
dist -> [ 0, 2, 3, 6, 4, 9007199254740991 ]
visited -> [ true, true, true, false, true, false ]
dist -> [ 0, 2, 3, 6, 4, 6 ]
visited -> [ true, true, true, false, true, true ]
[ 0, 2, 3, 6, 4, 6 ]
这样就会得到A到全部边的最短距离
[ 0, 2, 3, 6, 4, 6 ]
这就是js实现Dijkstra算法的过程,有些简短,有问题能够留言交流