Dijkstra算法 无向图

贪心法则

算法实现

先定义一个dist数组,用来存放原点到各个顶点的最小距离,初始化为无穷大,dist[原点]=0

再定义个visisted[],表示这个点有没有被访问

再定义个prev[i],如果prev[i]=j,表示结点i的前一个结点是j

  1. n个顶点,每次找最小的,一共找n-1次。
  2. 从dist中找到未标记的visisted[]=false的dist[i]最小的顶点u,则visisted[u]
  3. 再遍历u的邻接点j{j=0,1,...n},如果dist[u]+u到该点的距离 小于 dist[该点j],则更新dist[j]=dist[u]+u到该点的距离 ,则prev[j]=u

参考某博主

//
// Created by w on 2024/7/2.
//
#include <bits/stdc++.h>
#include <iostream>

using namespace std;
#define MVNum 100 //最大顶点数
#define MaxInt 10000//最大值
typedef  struct {
    char vexs[MVNum];//顶点表
    int arcs[MVNum][MVNum];//邻接矩阵
    int vexnum,arcnum;
}AMGraph;
//确定顶点位置,vexs[i]={A,B,C,D,E},v=B,返回1
int LocateVex(AMGraph* G,char v)
{
    int i;
    for(i=0;i<G->vexnum;i++)
    {
        if(G->vexs[i]==v)
            return i;
    }
    return -1;
}
//创建无向表
AMGraph* CreateUDN()
{
    int i,j,k,w;
    char v1,v2;
    AMGraph* G= (AMGraph*)malloc(sizeof (AMGraph));
    printf("输入总顶点数,边数:\n");
    cin>>G->vexnum>>G->arcnum;
    getchar();//吸收换行符
    printf("依次输入点的信息:\n");
    for(int i=0;i<G->vexnum;i++)
    {
        cin>>G->vexs[i];
    }
    getchar();
//    初始化邻接矩阵
    for(i=0;i<G->vexnum;i++)
    {
        for(j=0;j<G->vexnum;j++)
        {
            G->arcs[i][j]=MaxInt;
            if(i==j)
                G->arcs[i][j]=0;
        }
    }
    for(k=0;k<G->arcnum;k++)
    {
        printf("输入一条边依附的顶点及权值:\n");
        cin>>v1>>v2;
        cin>>w;
        getchar();
        i= LocateVex(G,v1);
        j= LocateVex(G,v2);
        G->arcs[i][j]=w;
        G->arcs[j][i]=w;//a到b是2,b到2也是2
    }
    return G;
}
int print(AMGraph* G)
{
    printf("  ");
    for(int i=0;i<G->vexnum;i++)
    {
        cout<<G->vexs[i]<<" ";//直观的显示j :ABCDEF
    }
    printf("\n");
    for(int i=0;i<G->vexnum;i++)
    {
        cout<<G->vexs[i]<<" ";//直观的显示i :ABCDEF
        for(int j=0;j<G->vexnum;j++)
        {
            if(G->arcs[i][j]==MaxInt)
                printf("∞ ");
            else
                cout<<G->arcs[i][j]<<" ";
        }
        printf("\n");
    }
}
int Dijkstra(AMGraph* G,int s)
{
    //s是起点
    int dist[MVNum];//储存顶点与各个顶点的最短距离
    int prev[MVNum];//从源到顶点i的最短路径i的前一个结点
    bool visited[MVNum];//判断结点没有被访问,先初始化为没有被访问
    int i,j,k,u,min;
//    初始化数组
    for(int i=0;i<G->vexnum;i++)
    {
        dist[i]=MaxInt;
        visited[i]=false;
        if(dist[i]==MaxInt)
            prev[i]=0;
        else
            prev[i]=s;
    }
    dist[s]=0;//此时dist[i]=0 maxin....
    for(k=1;k<G->vexnum;k++)//索引1 也就是第二个顶点开始询问
    {
        min=MaxInt;
        for(i=0;i<G->vexnum;i++)
        {
            if(dist[i]<min&&!visited[i])
            {
                u=i;
                min=dist[i];
            }//dist[0]<min u=i=0;min=0;
        }
        visited[u]= true;//0结点已被访问
//       遍历与u相连的结点(即u的邻接点),从原点s到u的距离是dist[u],u到下一个结点j的距离是G.arcs[u][j]
//       if (从s到u的距离)+(u到j的距离)小于(dist的初始化最小距离也可以说是原点到j的最小距离)
//       则更新dist[j]
        for(j=0;j<G->vexnum;j++)
        {
            if(!visited[j]&&dist[u]+G->arcs[u][j]<dist[j])
            {
                dist[j]=dist[u]+G->arcs[u][j];
                prev[j]=u;
            }
        }// 新的dist[i]=0 1 maxint....
    }
    for(i=0;i<G->vexnum;i++)
    {
        printf("从起点%c到%c的最短路径长度:%d\n",G->vexs[s],G->vexs[i],dist[i]);
        int p=prev[i];
        printf("path:%c",G->vexs[i]);
        while(p!=0)
        {
            printf("<-%c",G->vexs[p]);
            p=prev[p];
        }
        printf("<-%c\n",G->vexs[s]);
    }
}
int main()
{
    AMGraph* G=CreateUDN();
    printf("该无向图邻接矩阵为:\n");
    print(G);
    Dijkstra(G,0);
}
//输入总顶点数,边数:
//6 9
//依次输入点的信息:
//A B C D E F
//输入一条边依附的顶点及权值:
//AB 1
//输入一条边依附的顶点及权值:
//AC 4
//输入一条边依附的顶点及权值:
//BC 2
//输入一条边依附的顶点及权值:
//BD 7
//输入一条边依附的顶点及权值:
//BE 5
//输入一条边依附的顶点及权值:
//CE 1
//输入一条边依附的顶点及权值:
//DE 3
//输入一条边依附的顶点及权值:
//DF 2
//输入一条边依附的顶点及权值:
//EF 6

 

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值