原理
Dijkstra 核心就是用了贪心的思想。以局部最优解,求的所有的最优解。
例子
/**
* 待实现函数,在此函数中填入答题代码
* @param {number} routerNum
* @param {number[][]} linkDelays
* @param {number} routerRi
* @param {number} routerRj
* @return {number}
*/
const getMinDelay = (routerNum, linkDelays, routerRi, routerRj) => {
let graph = [];
// 无向图
linkDelays.forEach(item => {
let [start, end, delay] = item;
if (!graph[start - 1]) {
graph[start - 1] = []
}
if (!graph[end - 1]) {
graph[end - 1] = []
}
graph[start - 1][end - 1] = delay;
graph[end - 1][start - 1] = delay;
})
let visited = new Array(routerNum).fill(false);
let distance = new Array(routerNum).fill(Number.MAX_SAFE_INTEGER);
distance[routerRi - 1] = 0;
visited[routerRi - 1] = true;
// 取出源点到其他点的最短路径,后续更新pathNodes即可,返回 pathNodes[routerRj - 1]
let pathNodes = graph[routerRi - 1];
// 记录下次循环要遍历的点,即未确认最小距离的节点
let notes = [];
// 遍历 pathNodes, 获得 end 节点信息。
pathNodes.forEach((_ , index) => {
notes.push(index);
})
while (notes.length) {
// minNoteIndex 就是 end 节点
let minNoteIndex = notes[0];
let min = pathNodes[minNoteIndex];
// 在未确认最小距离的节点中找到值最小的note信息,以此为基点循环
notes.forEach(note => {
if (pathNodes[note] < min) {
minNoteIndex = note;
min = pathNodes[minNoteIndex];
}
})
// 如果本次循环确认的最小节点是目标节点
if (minNoteIndex === routerRj - 1) {
return min || -1;
}
// 已确认的节点从notes中删除
notes.splice(notes.indexOf(minNoteIndex), 1);
// 以该最小值的note为基点,来确认到达其他点的最小距离。
let endPathNotes = graph[minNoteIndex];
// 从graph中取出note的边,el为权重,index为目标节点
endPathNotes?.forEach((el, index) => {
// 如果 el + min 小于pathNotes中记录的值,则更新;如果pathNodes[index] 没有值,则记录下来
if (!pathNodes[index] || el + min < pathNodes[index]) {
pathNodes[index] = el + min;
notes.push(index)
}
})
}
return pathNodes[routerRj - 1]
};
// 路由数
let routerNum = 6;
// [start end 时延] = 1 2 2
let linkDelays = `1 2 2
1 3 4
2 5 3
5 6 2`.split('\n').map(item => item.split(' ').map((item) => Number(item)));
// 起始路由
let Ri = 2;
// 结束路由
let Rj = 6;
// 求 Ri -> Rj 的最小时延
console.log(getMinDelay(routerNum, linkDelays, Ri, Rj));