Dijkstra(迪杰斯特拉)算法-js实现

93 篇文章 1 订阅
5 篇文章 0 订阅

实现代码如下:

 var n = 3;
    var dis = [0];
    var mark = [];
    var arr = [];
    var inf = 9999;
    var i, j, k;
    //init
    for (i = 0; i < n; i++) {
        mark.push(1);
        arr[i] = [];
        for (j = 0; j < n; j++) {
            arr[i][j] = inf;//i->j,init 9999
        }
    }

    arr[0][1] = 3;
    arr[1][2] = -2;
    arr[0][2] = 6;

    //init dis

    dis[0] = 0;
    for (j = 1; j < arr.length; j++) {
        dis[j] = arr[0][j];
    }

    mark[0] = 0;
    for (i = 0; i < arr.length - 1; i++) {//去除源点自身,从剩下的点中选出离源点距离最小的点,因此只需进行n-1轮查找
        var min = [0, 0, inf];//src,dis,weight
        for (j = 0; j < arr.length; j++) {
            //找出最小值
            if (mark[j]) {
                if (arr[i][j] < min[2]) {
                    min = [i, j, arr[i][j]];
                }
            }
        }
        mark[min[1]] = 0;//将dis最小的点min[1]标记为选中

        for (k = 0; k < arr.length; k++) {//比较 min[1]->k + 源点到min[1]的距离dis[[min[1]]],是否比dis[k]的距离要小
            if (arr[min[1]][k] + dis[min[1]] < dis[k]) {
                dis[k] = arr[min[1]][k] + dis[min[1]];//松弛
            }

        }
    }

    console.log(dis);

迪杰斯特拉算法是求单源最短路径,思路是用一个dis数组保存源点到各点的距离(源点到自身的距离记为0),然后每次取距离最小的点,对这个点的所有出边进行松弛。
所谓松弛(relaxation),比如1->3=10,1->2->3=5,那么1->3实际上可缩短为5,这就叫做对边1->3进行了一轮松弛操作。
最近在看《啊哈!算法》,书上说迪杰斯特拉算法不能有负权边,我用js写的这个,试了一下负权边好像是可以的,只是不能有负权回路,然后看了书上的Bellman-ford算法,我觉得除了加上了负权回路的判断好像和迪杰斯特拉算法没什么区别。。。嗯,应该是我没看懂= =
我用js实现了负权回路的判断,代码如下:

var n = 3;
    var dis = [0];
    var mark = [];
    var arr = [];
    var inf = 9999;
    var i, j, k;
    //init
    for (i = 0; i < n; i++) {
        mark.push(1);
        arr[i] = [];
        for (j = 0; j < n; j++) {
            arr[i][j] = inf;//i->j,init 9999
        }
    }

    arr[0][1] = 3;
    arr[1][2] = 2;
    arr[0][2] = 6;
    arr[2][0] = -1;

    //init dis

    dis[0] = 0;
    for (j = 1; j < arr.length; j++) {
        dis[j] = arr[0][j];
    }

    mark[0] = 0;
    for (i = 0; i < arr.length - 1; i++) {//去除源点自身,从剩下的点中选出离源点距离最小的点,因此只需进行n-1轮查找
        var min = [0, 0, inf];//src,dis,weight
        for (j = 0; j < arr.length; j++) {
            //找出最小值
            if (mark[j]) {
                if (arr[i][j] < min[2]) {
                    min = [i, j, arr[i][j]];
                }
            }
        }
        mark[min[1]] = 0;//将dis最小的点min[1]标记为选中

        for (k = 0; k < arr.length; k++) {//比较 min[1]->k + 源点到min[1]的距离dis[[min[1]]],是否比dis[k]的距离要小
            if (arr[min[1]][k] + dis[min[1]] < dis[k]) {
                dis[k] = arr[min[1]][k] + dis[min[1]];//松弛
                arr[0][k] = dis[k];//同时修改数组值,用于判断是否有负权回路
            }

        }
    }

    console.log(dis);

    /*检测是否有负权回路*/
    for (i = 0; i < arr.length; i++) {
        for (j = 0; j < arr.length; j++) {
            if (arr[0][j] > dis[i] + arr[i][j]) {
                console.log("有负权回路", "0->", i, "->", j);
                break;
            }
        }
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Dijkstra迪杰斯特拉算法是一种典型的最短路径算法,可以用于计算一个节点到其他节点的最短路径。它的主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止,使用的是广度优先搜索的思想。该算法通过不断更新起始点到其他节点的距离,选择当前距离最短的节点进行扩展,直到所有节点都被扩展完毕,找到起始点到其他节点的最短路径。Dijkstra算法在网络路由、地图导航等领域有广泛应用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [C++实现Dijkstra(迪杰斯特拉)算法](https://download.csdn.net/download/weixin_38692122/12724830)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Dijkstra迪杰斯特拉算法](https://blog.csdn.net/qq_43461641/article/details/100632351)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [DijkstraAlgorithm(迪杰斯特拉算法)](https://blog.csdn.net/qq_45740348/article/details/113575420)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值