# 狄克斯特拉算法
来源: 图解算法第七章
- 寻找加权图中前往X的最短路径
- 图中不可以存在环
- 负权边会导致算法失效
算法实现:
// 问题描述: 寻找从起点到终点最短时间的路径
// 案例1:
let graph = {}
graph['start'] = {}
graph['a'] = {}
graph['b'] = {}
graph['end'] = {}
graph['start']['a'] = 6
graph['start']['b'] = 2
graph['a']['end'] = 1
graph['b']['a'] = 3
graph['b']['end'] = 5
graph['end']['c'] = 8
let res = findShortestMap(graph, 'start', 'end')
console.log(res) // ['start', 'b', 'a', 'end']
// 案例2
let graph = {}
graph['start'] = {}
graph['a'] = {}
graph['b'] = {}
graph['c'] = {}
graph['d'] = {}
graph['end'] = {}
graph['start']['a'] = 5
graph['start']['b'] = 2
graph['a']['c'] = 4
graph['a']['d'] = 2
graph['b']['a'] = 8
graph['b']['d'] = 7
graph['c']['d'] = 6
graph['c']['end'] = 3
graph['d']['end'] = 1
// ['start', 'a', 'd', 'end']
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 代码实现
function findShortestMap (data, startKey, endKey) {
let constGraph = {}
let parentGraph = {}
let processed = [] // 已经寻找过的节点
if (!data[startKey]) {
return null
}
// 初始化 const 数据
let node = data[startKey]
let currentKey = startKey
Object.keys(node).forEach(key => {
constGraph[key] = node[key]
parentGraph[key] = currentKey
})
constGraph[endKey] = Number.MAX_SAFE_INTEGER - 1
// 开始
currentKey = findLowestCostNode()
node = data[currentKey]
while (node) {
if (currentKey === endKey) {
return getResult()
}
let cost = constGraph[currentKey]
Object.keys(node).forEach(key => {
let newCost = cost + node[key]
if (!constGraph[key]) {
constGraph[key] = newCost
parentGraph[key] = currentKey
} else if (constGraph[key] > newCost) {
constGraph[key] = newCost
parentGraph[key] = currentKey
}
})
processed.push(currentKey)
currentKey = findLowestCostNode()
node = data[currentKey]
}
function findLowestCostNode() {
let lowestCost = Number.MAX_SAFE_INTEGER
let lowestCostNode = null
Object.keys(constGraph).forEach(key => {
if (constGraph[key] < lowestCost && !processed.includes(key)) {
lowestCostNode = key
lowestCost = constGraph[key]
}
})
return lowestCostNode
}
function getResult() {
if (parentGraph && parentGraph[endKey]) {
let res = [endKey]
let preStep = parentGraph[endKey]
while (preStep) {
res.push(preStep)
preStep = parentGraph[preStep]
}
return res.reverse()
}
return null
}
return getResult()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67