Dijkstra 算法的 邻接矩阵和邻接表的C++

这是对两种数据结构的实现方式的具体的代码:

在看代码之前,需要了解什么时邻接矩阵和邻接表,请看别人写的博客:

https://blog.csdn.net/daocaoren_/article/details/98632474

对于Dijkstra算法的介绍就不介绍了,因为网上有很多

  1. 邻接矩阵的实现代码:

//假设:
//1.我们已经有了一个邻接矩阵的数据G,G[i][j]表示从顶点i到顶点j的距离
//2.我们从st顶点出发
//3.我们有vernum个顶点
//4.int dist[vernum]数组;dise[i]表示i顶点到Vs集合的距离;vs指的是已经遍历过的节点
//5.int used[vernum]数组;used[i]==1表示i顶点已经加入了vs集合;vs初始只有st节点
#define inf  999999
Dijkstra(Graphic G,int st)
{
    //初始化
    for(int i=0;i<vernum;++i)
    {
        used[i]=0;   //初始时所有的顶点都没有加入VS集合
        dist[i]=inf; //初始时所有的顶点到VS集合的距离都是无穷
        if(dist[i]>G[st][i])
            dist[i]=G[st][i]; //随便把源顶点可达的顶点距离更新
    }
    
    //开始加入第一个顶点(假设5)
    used[st]=1;
    dist[st]=0; //所有顶点到自身的距离都是0

    //下面开始真正的算法核心
    for(int i=0;i<vernum;++i) //遍历所有的顶点
    {
        //第一步:找到距离到集合vs最短的顶点
        int pos=1; //记录距离到集合vs最短的顶点
        int tmp_dist=inf; 
        for(int j=0;j<vernum;++j)  
        {
            //找到一个顶点离vs集合最近
            if(used[j]==0 && dist[j]<tmp_dist)
            {
                pos=j;
                tmp_dist=dist[j];//记录这个顶点到VS的距离
            }
        }
        //第二步:把找到的顶点加入vs中
        used[pos]=1;
        
        //第三步:更新未加入vs的顶点到vs集合的距离
        for(int j=0;j<vernum;++j)
        {
            if(used[j]==0 && dist[j]>G[pos][j]+tmp_dist) //如果G[pos][j]==inf,那么将不会更新
                dist[j]=G[pos][j]+tmp_dist;
        }
    }
    
}

  1. 邻接表的实现:

参考博客:

https://blog.csdn.net/m0_51657509/article/details/128068016

//假设:
//1.我们有邻接表L
//2.我们有dist[vernum],used[vernum]和上个例子的一样
//3.prev[vernum]矩阵,prev[i]表示i顶点的前一个顶点,可以用来打印路径
//4.st为开始顶点
//5.getdistance(L,st,end),表示邻接表中从st到end顶点的距离
#define inf  999999
Dijkstra(Adjlist &L,int st,vector<int>&dist,vector<int>&prev)
{
    //初始化
    for(int i=0;i<vernum;++i)
    {
        used[i]=0;
        prev[i]=st;  //一开始所有的顶点都以st为前顶点,即以st为出发点
        dist[i]=getdistance(L,st,i);
    }
    //开始加入第一个顶点
    used[st]=1
    
    //下面开始真正的算法核心
    for(int i=0;i<vernum;++i)
    {
        //第一步:找到距离到集合vs最短的顶点
        int pos=1; //记录距离到集合vs最短的顶点
        int tmp_dist=inf; 
        for(int j=0;j<vernum;++j)  
        {
            //找到一个顶点离vs集合最近
            if(used[j]==0 && dist[j]<tmp_dist)
            {
                pos=j;
                tmp_dist=dist[j];//记录这个顶点到VS的距离
            }
        }
        //第二步:把找到的顶点加入vs中
        used[pos]=1;
        //第三步:更新未加入vs的顶点到vs集合的距离
        for(int j=0;j<vernum;++j)
        {
            if(used[j]==0 && dist[j]>getdistance(L,pos,j)+tmp_dist) //如果getdistance(L,pos,j)==inf,那么将不会更新
             {
                dist[j]=getdistance(L,pos,j)+tmp_dist;
                prev[j]=pos;  //说明顶点j可以由顶点pos到达
             }
        }        
    }
}

getdistance(Adjlist & L,int & st,int & end)
{
    if(st==end)
        return 0;

    ArcNode* tmp = G.adjlist[st].firstedge;
    while(tmp){
        if(tmp->adjvex == end) return tmp->weight;
        tmp = tmp->next;
    }  
    return inf;
}

// 邻接表
struct ArcNode // 边信息
{
    int adjvex;//有向边的 目标顶点 下标(从1开始)
    int weight;//边的权值
    struct ArcNode *next; //邻接表,指向下一个邻接边信息
};
 
struct VertexNode // 顶点
{
    int vertex;//顶点下标(1 ~)
    ArcNode *firstedge;// 有向边信息节点指针(源为vertex)
};
 
struct AdjList // 图
{
    vector<VertexNode> adjlist;//顶点数组
    int vexnum;  //顶点数 
    int arcnum;  //边数
};
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值