鱼C论坛

 找回密码
 立即注册
查看: 2537|回复: 0

[技术交流] 图的两个最短路径算法(邻接表实现)

[复制链接]
发表于 2018-11-8 15:30:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
        写了两个最短路径算法的邻接表版,但并没测试过,所以可能有错误,若发现有错误,可以在下面留言。
  1. //AdjList.h
  2. #pragma once
  3. //邻接表的储存结构

  4. #define INFINITY 0
  5. #define MAX_VERTEX_NUM 1025

  6. typedef struct ArcNode
  7. {
  8.         int adjvex;
  9.         struct ArcNode *nextarc;
  10.         int weight;
  11. }ArcNode;

  12. typedef struct VNode
  13. {
  14.         VertexType data;
  15.         ArcNode *firstarc;
  16. }VNode,AdjList[MAX_VERTEX_NUM];

  17. typedef struct
  18. {
  19.         AdjList vertices;
  20.         int vexnum, arcnum;
  21.         int kind;
  22. }ALGraph;


  23. //ShortestPath.h
  24. #pragma once
  25. #include "AdjList.h"
  26. //最短路径——迪杰斯特拉算法和弗洛伊德算法(邻接表版)
  27. //这里所有数组中的0下标都未使用

  28. typedef int PathArc[MAX_VERTEX_NUM];        //用来储存最短路径前驱下标的数组
  29. typedef int ShortPathTable[MAX_VERTEX_NUM];        //用来储存到各点的权值和

  30. //函数功能:寻找v0到v1顶点的直连路径长度
  31. //函数参数:图的邻接表G,起始顶点v0,到达顶点v1
  32. //函数返回值:直连路径的长度,若没有直连长度,返回INFINITY
  33. int PathDistance(ALGraph G, int v0, int v1);

  34. //函数功能:自定义比较路径长度
  35. //函数参数:要比较的路径长度distance1和distance2
  36. //函数返回值:-1代表前一个参数小于后一个参数,0代表两者相等,1代表前一个参数大于后一个参数
  37. int PathCompare(int distance1, int distance2);

  38. //函数功能:自定义路径相加
  39. //函数参数:要相加的两个路径长度distance1和distance2
  40. //函数返回值:两个路径长度相加的结果
  41. int PathAdd(int distance1, int distance2);

  42. //函数功能:寻找一个顶点到其余各点的最短路径(迪杰斯特拉算法)
  43. //函数参数:图的邻接表G,起始顶点v0,最短路径前驱下标的数组P,到各点的长度S
  44. //函数返回值:void
  45. void ShortestPath_DIJ(ALGraph G, int v0, PathArc P, ShortPathTable S);

  46. //函数功能:寻找一个顶点到其余各点的最短路径(弗洛伊德算法)
  47. //函数参数:图的邻接表G,储存各点到其他点的最短路径的前驱顶点P[],储存各点到其他点的最短路径的长度S[]
  48. //函数返回值:void
  49. void ShortestPath_FLOYD(ALGraph G, PathArc p[], ShortPathTable S[]);



  50. //ShortestPath.c
  51. #include <stdio.h>
  52. #include <stdlib.h>
  53. #include "ShortestPath.h"

  54. //最短路径——迪杰斯特拉算法和弗洛伊德算法(邻接表版)
  55. //实现部分

  56. //函数功能:寻找v0到v1顶点的直连路径长度
  57. //函数参数:图的邻接表G,起始顶点v0,到达顶点v1
  58. //函数返回值:直连路径的长度,若没有直连长度,返回INFINITY
  59. int PathDistance(ALGraph G, int v0, int v1)
  60. {
  61.         ArcNode *arcNode;

  62.         arcNode = G.vertices[v0].firstarc;
  63.         while (arcNode != NULL && arcNode->adjvex != v1)
  64.         {//寻找直连路径
  65.                 arcNode = arcNode->nextarc;
  66.         }
  67.         if (arcNode != NULL)
  68.         {//找到直连路径时,返回直连路径长
  69.                 return arcNode->weight;
  70.         }
  71.         else
  72.         {//未找到直连长度时,返回INFINITY
  73.                 return INFINITY;
  74.         }
  75. }

  76. //函数功能:自定义比较路径长度
  77. //函数参数:要比较的路径长度distance1和distance2
  78. //函数返回值:-1代表前一个参数小于后一个参数,0代表两者相等,1代表前一个参数大于后一个参数
  79. int PathCompare(int distance1, int distance2)
  80. {
  81.         if (distance1 == INFINITY)
  82.         {
  83.                 if (distance2 == INFINITY)
  84.                 {
  85.                         return 0;
  86.                 }
  87.                 else
  88.                 {
  89.                         return 1;
  90.                 }
  91.         }
  92.         else if (distance2 == INFINITY)
  93.         {
  94.                 return -1;
  95.         }
  96.         else
  97.         {
  98.                 distance1 >= distance2 ? (distance1 == distance2 ? 0 : 1) : -1;
  99.         }
  100. }

  101. //函数功能:自定义路径相加
  102. //函数参数:要相加的两个路径长度distance1和distance2
  103. //函数返回值:两个路径长度相加的结果
  104. int PathAdd(int distance1, int distance2)
  105. {
  106.         if (distance1 == INFINITY || distance2 == INFINITY)
  107.         {
  108.                 return INFINITY;
  109.         }
  110.         else
  111.         {
  112.                 return distance1 + distance2;
  113.         }
  114. }

  115. //函数功能:寻找一个点到其余各点的最短路径(迪杰斯特拉算法)
  116. //函数参数:图的邻接表G,起始顶点v0,最短路径前驱下标的数组P,到各点的长度S
  117. //函数返回值:void
  118. void ShortestPath_DIJ(ALGraph G, int v0, PathArc P, ShortPathTable S)
  119. {
  120.         int w,v;
  121.         int min;
  122.         int final[MAX_VERTEX_NUM];        //记录是否找到某一顶点的最短路径
  123.         for (v = 1; v <= G.vexnum; v++)
  124.         {//初始化
  125.                 final[v] = 0;
  126.                 P[v] = v0;
  127.                 S[v] = PathDistance(G, v0, v);
  128.         }
  129.         final[v0] = 1; S[v0] = 0;        //顶点v0到自身的路径为0
  130.         for (int i = 2; i <= G.vexnum; i++)
  131.         {//找其余vexnum-1个顶点的最短路径所以需要有vexnum-1重循环
  132.                 min = INFINITY;
  133.                 for (w = 1; w <= G.vexnum; w++)
  134.                 {//寻找此时v0到哪个顶点的路径最短
  135.                         if (!final[w] && PathCompare(S[w], min) < 0)
  136.                         {//找到更短路径,更新路径最小值
  137.                                 v = w;
  138.                                 min = S[w];
  139.                         }
  140.                 }
  141.                 if (min == INFINITY)        break;        //若在一次查找中,找不到最短路径,则整个循环结束
  142.                 final[v] = 1;
  143.                 for (w = 1; w <= G.vexnum; w++)
  144.                 {//通过此次找到的最短路径的顶点来更新到其他顶点的路径
  145.                         if (!final[w] && PathCompare(PathAdd(min, PathDistance(G, v, w)), S[w]) < 0)
  146.                         {//说明找到了更短的路径,更新到该顶点的前驱结点和最短路径
  147.                                 S[w] = PathAdd(min, PathDistance(G, v, w));
  148.                                 P[w] = v;
  149.                         }
  150.                 }
  151.         }
  152. }

  153. //函数功能:寻找一个顶点到其余各点的最短路径(弗洛伊德算法)
  154. //函数参数:图的邻接表G,储存各点到其他点的最短路径的前驱顶点P[],储存各点到其他点的最短路径的长度S[]
  155. //函数返回值:void
  156. void ShortestPath_FLOYD(ALGraph G, PathArc P[], ShortPathTable S[])
  157. {
  158.         int k, w, v;
  159.         for (v = 1; v <= G.vexnum; v++)
  160.         {
  161.                 for (w = 1; w <= G.vexnum; w++)
  162.                 {//初始化
  163.                         P[v][w] = v;        //假设w到v的直连路径最短
  164.                         S[v][w] = PathDistance(G, v, w);       
  165.                 }
  166.         }

  167.         for (k = 1; k <= G.vexnum; k++)
  168.         {
  169.                 for (v = 1; v <= G.vexnum; v++)
  170.                 {
  171.                         for (w = 1; w <= G.vexnum; w++)
  172.                         {
  173.                                 if (PathCompare(S[v][w], PathAdd(S[v][k], S[k][w])) > 0)
  174.                                 {//如果经过下标为k的顶点的路径更短,更新最短路径
  175.                                         P[v][w] = S[k][w];
  176.                                         S[v][w] = PathAdd(S[v][k], S[k][w]);
  177.                                 }
  178.                         }
  179.                 }
  180.         }
  181. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-13 23:46

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表