第0篇--Dijkstra算法的实现

  • 去年大一的时候就学过Dijkstra,但是当时候为了添加什么功能把代码改崩了,后来重装系统后就找不到代码在哪里放的了,今天刚好写报告要用,所以没看别人的博客自己重新写了一下。

  • 目前输出是倒序输出的,不太直观,其他的都实现了,如果想改成手动输入初始化一些边点可以自己动手改一下Initialization函数,如果要输出任意两点间的最短距离,在循环外层再加一层函数,让后改掉相应参数即可。

算法暂时就不展开讲了,网上有很多,我先把重点放在代码实现上。

  • 下面是代码:
#include<stdio.h>
#include<stdlib.h>

//初始化数组
void Initialization(int point[][6])
{
    for (int i = 0; i < 6; ++i)
    {
        for (int j = 0; j < 6; ++j)
        {
            if (i == j)
            {
                point[i][j] = 0;
            }
            else
            {
                point[i][j] = -1;
                continue;
            }
        }
    }
    //有向图的初始化(示例)
    //point[0][2] = 10;
    //point[0][4] = 30;
    //point[0][5] = 100;
    //point[1][2] = 5;
    //point[2][3] = 50;
    //point[4][3] = 20;
    //point[3][5] = 10;
    //point[4][5] = 60;

    //无向图的初始化(示例)
    point[0][2] = point[2][0] = 10;
    point[0][4] = point[4][0] = 30;
    point[0][5] = point[5][0] = 100;
    point[1][2] = point[2][1] = 5;
    point[2][3] = point[3][2] = 50;
    point[3][4] = point[4][3] = 20;
    point[3][5] = point[5][3] = 10;
    point[4][5] = point[5][4] = 60;
}

//寻找从第0个点到各点的最短路径
void Dijkstra(int point[][6])
{
    int road[6];                        //用来存放点的访问顺序
    int distance;                       //用来存放距离
    int dis[6];                         //用来存放第0个点到各点的最短距离
    int flag[6];                        //用来标记各点是否被访问过
    for (int i = 0; i < 6; ++i)
    {
        dis[i] = INT_MAX;               //初始化第零个点到各点的最短距离
        flag[i] = 0;                    //初始化标记
        road[i] = -1;
    }

    dis[0] = 0;                         //标记第0个点到自身的距离为0
    distance = dis[0];                  //distance=dis[0],用来存放第0个点到上次得出距离最小点的与第0个点间距离
    flag[0] = 1;                        //标记第0个点为已访问的点
    road[0] = 0;
    int minpoint = 0, temppoint = 0;    //minpoint为每次循环后距离最小的点,temppoint用来临时存放最小的点
    for (int i = 1; i < 6; ++i)
    {
        int mindistance = INT_MAX;
        distance = dis[minpoint];
        for (int j = 1; j < 6; ++j)
        {
            if (!flag[j] && minpoint != j)  //如果没访问过该点且不是自身到自身
            {
                //如果minpoint到j点有路且当前点的权值加上两点间的距离比原先距离小则更新
                if (point[minpoint][j] != -1 && point[minpoint][j] + distance < dis[j])
                {
                    dis[j] = point[minpoint][j] + distance;
                    road[j] = minpoint;
                }
            }
            //在循环的同时更新并标记未访问过的点的最小距离和所对应的点
            if (!flag[j] && dis[j] < mindistance)
            {
                mindistance = dis[j];
                temppoint = j;
            }
        }


        minpoint = temppoint; //循环结束,标记距离最小点被访问过
        flag[minpoint] = 1;
        for (int k = 0; k < 6; ++k) //为了便于理解,输出每次遍历后第0个点到其他点的距离
        {
            if (dis[k] == INT_MAX)
            {
                printf("∞\t");
            }
            else
            {
                printf("%d\t", dis[k]);
            }
        }
        printf("\n");
    }

    for (int k = 0; k < 6; ++k)
    {
        int t = k;
        if (road[t] >=0)
        {
            printf("%d <- ", t);
            while (road[road[t]] != road[t])
            {
                printf("%d <- ", road[t]);
                t = road[t];
            }
            printf("%d\n", road[t]);
        }   
    }
}

int main()
{
    int point[6][6];         //定义数组
    Initialization(point);   //初始化数组
    Dijkstra(point);         //求第0个点到各点的最小距离
    return 0;
}
  • 输出:

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值