算法简易过程:

  •  迪杰斯特拉算法(朴素) O(n^2)
    G={V,E}   V:点集合   E:边集合
    初始化时 令 S={某源点ear}, T=V-S= {其余顶点},T中顶点对应的距离(ear, Vi)值若存在,d(ear,Vi)为弧上的权值, dist【i】若不存在,d(ear,Vi)为 无穷大, dist【i】循环 n - 1次(n个点):1、从T中选取一个与S中顶点 有关联边 且 权值最小 的顶点 pos,加入到 S中(这里使用 flag数组来确定 是否属于 S集合,true为属于)(等于是 每次 选取 T点集中 dist最小的顶点 作为 pos 加入 S,既 flag置为 true)2、对其余T中顶点Vi的距离值进行修改:若加进 pos 作中间顶点,从ear -> pos -> Vi 的距离值缩短,则   更新dist(等于是 找出所有 pos -> Vi 边(有边连接的), 再加上原来源ear -> pos 权重,对比dist数组,如果权重更小则更新 => 更新dist最短路径长度,更新prev数组 更新前驱顶点为pos)

求单源有向图最短路径

使用邻接表法来存储顶点和边,录入有向图

(当然也可以无向图,不过录入时要录入两次,比如 a b 3        b a 3)

代码如下:

//
// Created by Giperx on 2022/11/27.
//
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
#define INFINE 99999 // 定义最大
// 邻接表
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;  //边数
};// 图的初始化
void createGraph(AdjList& G){cout << "输入顶点数 边数:" << endl;cin >> G.vexnum >> G.arcnum;// 初始化G的顶点数组for(int i = 0; i <= G.vexnum; i ++){ // 下标从1开始,所以初始化vexnum + 1个顶点(0无作用)VertexNode* tmp = new VertexNode;tmp->vertex = i, tmp->firstedge = nullptr;G.adjlist.emplace_back(*tmp);}//边信息// n1:源顶点     n2:目标顶点   we:权重(距离)int n1, n2, we;cout << "输入边信息:(a b we):" << endl; // a -> b  weight: wefor(int i = 0; i < G.arcnum; i ++){cin >> n1 >> n2 >> we;// 初始化一个边节点,目标顶点为n2ArcNode* tmp = new ArcNode;tmp->adjvex = n2, tmp->weight = we;// 头插法 将边信息节点插入// 节约时间(尾插要一直遍历到尾部插入)tmp->next = G.adjlist[n1].firstedge;G.adjlist[n1].firstedge = tmp;}
}// 获取两顶点之间权重weight(距离)
int getWeight(AdjList& G, int n1, int n2){if(n1 == n2) return 0;ArcNode* tmp = G.adjlist[n1].firstedge;while(tmp){if(tmp->adjvex == n2) return tmp->weight;tmp = tmp->next;}// 两点之间没有边,返回INFINEreturn INFINE;
}// 迪杰斯特拉算法(朴素)
//G={V,E}   V:点集合   E:边集合
//初始化时 令 S={某源点ear}, T=V-S= {其余顶点},T中顶点对应的距离(ear, Vi)值
//          若存在,d(ear,Vi)为弧上的权值, dist【i】
//          若不存在,d(ear,Vi)为 无穷大, dist【i】
// 循环 n - 1次(n个点):
//  从T中选取一个与S中顶点 有关联边 且 权值最小 的顶点 pos,加入到 S中
//      (这里使用 flag数组来确定 是否属于 S集合,true为属于)
//      (等于是 每次 选取 T点集中 dist最小的顶点 作为 pos 加入 S,既 flag置为 true)
//  对其余T中顶点Vi的距离值进行修改:若加进 pos 作中间顶点,从ear -> pos -> Vi 的距离值缩短,则 更新dist
//      (等于是 找出所有 pos -> Vi 边(有边连接的), 再加上原来源ear -> pos 权重,
//      对比dist数组,如果权重更小则更新 => 更新dist最短路径长度,更新prev数组 更新前驱顶点为pos)
void Dijkstra(AdjList& G, int ear, vector<int>& prev, vector<int>& dist){// 初始化// flag数组记录 某点是否纳入已找到点集合// prev数组记录 前驱顶点下标// dist数组记录 从源顶点ear 到 i顶点的最短路径vector<bool> flag (G.adjlist.size() + 1, false);for(int i = 1; i <= G.vexnum; i ++) dist[i] = getWeight(G, ear, i), prev[i] = ear;flag[ear] = true, prev[ear] = 0;// 开始for(int i = 2; i <= G.vexnum; i ++){int pos = 1; // 未纳入的距离最小的顶点int weiMin = INFINE;for(int j = 1; j <= G.vexnum; j ++){if(!flag[j] && dist[j] < weiMin){weiMin = dist[j], pos = j;}}flag[pos] = true;for(int j = 1; j <= G.vexnum; j ++){if(!flag[j]){ // 未纳入点集中,找到pos到这些点的距离,与dist数组比较是否更新int tmpWei = getWeight(G, pos, j);if(tmpWei != INFINE) tmpWei = tmpWei + weiMin; // 两点距离应该为ear -> pos -> jif(tmpWei < dist[j]) {dist[j] = tmpWei; // 距离更小则更新distprev[j] = pos; // 前顶点更新为pos}}}}}// 找路径
void pathDist(vector<int>& prev, vector<int>& dist, int ear){// prev数组中为1有2种情况(djikstra初始化过程的时候全赋值为1,后续一直未改变):// 1:从ear到 顶点 只有 ear -> 顶点 这一条路最短// 2:无法从ear到达的顶点for(int i = 1; i <= prev.size() - 1; i ++){stack<int> trace;if(ear == i) continue;cout << ear << " 到 " << i ;// 无连通if(dist[i] == INFINE) {cout << "无连通" << endl;continue;}cout << "最短距离:" << dist[i] << "  最短路径:";int tmp = i;while(tmp){ //  源顶点prev是0trace.push(tmp);tmp = prev[tmp];}// 开始出栈, 栈顶一定是ear源顶点cout << trace.top();trace.pop();while(!trace.empty()){cout << " -> " << trace.top();trace.pop();}cout << endl;}
}
int main(){AdjList G;createGraph(G);// prev数组记录 前驱顶点下标vector<int> prev (G.vexnum + 1, 0);// dist数组记录 从源顶点ear 到 i顶点的最短路径vector<int> dist (G.vexnum + 1, INFINE);// 从源点ear 出发,到达其余所有点的最短路径cout << "输入源顶点ear:";int ear;cin >> ear;Dijkstra(G, ear,prev, dist);pathDist(prev, dist, ear);
//    for(int &x:prev) cout << x << ' ';
//    for(int &x:dist) cout << x << ' ';return 0;
}

测试如下:

dijkstra迪杰斯特拉算法(邻接表法)相关推荐

  1. JavaScript实现dijkstra迪杰斯特拉算法(附完整源码)

    JavaScript实现dijkstra迪杰斯特拉算法 PriorityQueue完整源代码 MinHeap.js完整源代码 Heap.js完整源代码 Comparator.js完整源代码 dijks ...

  2. C++实现Dijkstra(迪杰斯特拉)算法(附完整源码)

    C++Dijkstra迪杰斯特拉算法的实现 C++Dijkstra(迪杰斯特拉)算法的完整源码(定义,实现,main函数测试) C++Dijkstra(迪杰斯特拉)算法的完整源码(定义,实现,main ...

  3. Dijkstra迪杰斯特拉算法 C++实现

    本篇文章主要介绍了Dijkstra迪杰斯特拉算法的C++实现,文章包含两个部分,在第一部分中我会简单介绍迪杰斯特拉算法以及一些个人的理解,第二部分会对C++代码的逻辑进行解释.下面是我已经上传的代码资 ...

  4. Dijkstra(迪杰斯特拉)算法求单源最短路径问题

    Dijkstra(迪杰斯特拉)算法求单源最短路径问题 重要的事情说三遍:代码不是我写的!代码不是我写的!代码不是我写的! 第一个算法是严蔚敏数据结构(C语言版)上写的,第二个算法是王道数据结构上写的, ...

  5. 最短路径之Dijkstra(迪杰斯特拉)算法(无向图)

    简介      Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.由for循环可知,其时间 ...

  6. MATLAB轻松绘制地图路线——Dijkstra(迪杰斯特拉)算法最短路径规划

    文章目录 1. 地图绘制 2. 计算各节点之间的距离 3. Dijkstra(迪杰斯特拉)算法 4. 根据计算出的距离利用Dijkstra(迪杰斯特拉)算法找出指定节点之间的最短路径 工程文件(可直接 ...

  7. 算法提升:图的Dijkstra(迪杰斯特拉)算法

    目录 概念 思路 代码 概念 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路 ...

  8. C语言实现Dijkstra(迪杰斯特拉)算法(附完整源码)

    Dijkstra迪杰斯特拉 Graph结构体定义 迪杰斯特拉算法完整源码(定义,实现,main函数测试) Graph结构体定义 struct Graph {int vertexNum;int **ed ...

  9. Dijkstra(迪杰斯特拉)算法

    一.简介 迪克斯特拉算法又名Dijkstra算法(属于贪心算法).Dijkstra算法是从一节点到其余各节点最短路径计算方法. 迪杰斯特拉算法以起始点为中心向外层层扩展,直到扩展到终点为止. 算法思想 ...

最新文章

  1. 使用SysPrep制作Windows2008系统映像
  2. 腾讯云数据库 MySQL 8.0 正式上线,性能全面超越官方版本
  3. (转)Caffe搭建:常见问题解决办法和ubuntu使用中遇到问题(持续更新)
  4. OpenMP 并行程序设计入门
  5. vue的一些坑(第二天)
  6. python爬取百度迁徙数据_python爬虫-动态爬取百度迁徙
  7. 计算机表格怎么算加减,excel表格数据的加减-excel表格怎么自动计算加减
  8. drozer安装使用问题总结
  9. jpg转pdf怎么转换免费
  10. mac DOSBox快捷键
  11. 微信授权登录增加浏览器历史记录解决方法
  12. 产品助理入门攻略(一枚入行3年的PM内心独白)
  13. C# 调用outlook 收发邮件
  14. linux卸载致远oa,致远oa(seeyon)文件上传漏洞重现及分析
  15. 程序员赚的辛苦钱及好朋友借钱[借钱时你是爷爷,借出去后丢一个朋友不说还多出一个爷爷]
  16. 基于小鼠的基因集数据库资源(人鼠基因集比较)
  17. 汉语拼音大全(竖排版)
  18. 等保2.0参与医院网络安全管理的重要性
  19. Pytorch transformers tokenizer 分词器词汇表添加新的词语和embedding
  20. 【安装】wsl ubuntu18.04安装libc6:i138报错E: Unable to locate package libc6-i386及解决

热门文章

  1. 离奇电信诈骗:一夜损失 52000元,毒品、情妇、黑客交织的犯罪网络
  2. 算法工程师实习总结(7-9)
  3. “百思不得姐,2021最新Java面试笔试题目分享
  4. 再回首 --- 零点伤感
  5. 八卦和天干地支的正确读音
  6. HDU - 4737 A Bit Fun 暴力水题
  7. 《Neural Machine Translation: Challenges, Progress and Future》译文分享
  8. 优质的游戏-cc协议2d素材库素材推荐,不容错过
  9. STM32 12864串行驱动
  10. 51单片机入学第一课———点亮自己的LED灯珠