最短路径问题:
从图的一个顶点出发,到达图的另一个顶点的最短路径
解法:
迪杰斯特拉算法(Dijkstra算法)
弗洛伊德算法(Floyd算法)
SPFA算法
Dijkstra算法介绍
主要是通过广度优先遍历,对每个点进行松弛操作找到源点到其他每个点的最短路径
具体实现流程:
一、初始化图
1、首先定义图的结构体包含邻接数组和顶点数组
2、然后输入每一个顶点的值,然后按输入顶点顺序来输入邻接数组的每个值
3、为了方便自己到自己可以设置为0,没有路径设置为-1,有路径设置路径值
4、对邻接数组进行加工,把距离为-1的设置为默认的无穷大
二、通过Dijkstra求最短路径
思想:通过一个距离数组不断松弛求最短路径,松弛过程中记录通过的点
第一次将源点的数据记录到距离数组并将源点标记,然后依次找最近的未标记的点进行松弛操作,所有的点标记后得到的数组就是到其他每个点的最短距离,可以通过前驱节点来找到对应的路径。
松弛操作:比如1 2 3 4四个顶点求1到4的最短路径,首先加入1,通过邻接矩阵得到1到其他每个点的最短路径,然后加入离1最近的点(比如3),松弛 其他距离(判断1到2的直接距离小还是通过3到2 的间接距离小)(判断1到4的直接距离小还是通过3到4的间接距离小),依次对其他每个未标记的点进行判断取最小
5、首先定义需要的数组,包含used判断每个顶点是否已经被标记
6、通过距离数组记录源点到其他点的距离
7、前驱节点数组用来记录当前节点离源点最近的路径的上一个点,用来寻找最短路径
8、初始化数组,标记数组都设置为未标记,源点设置为已标记,距离数组读取邻接矩阵中源点的行,前驱节点都设置为自己
9、从源点开始找最近的点一次进行松弛操作,找到最近且未标记的点,判断到其他未标记的点是不是可以通过这个新加入的点所短路径,如果可以缩短就修改距离和前驱阶段,直到所有顶点都被标记
10、通过前驱节点数组找到对应路径,通过距离数组得到最短值。
实现代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> #define MaxSize 20 #define INFINITY 666 typedef char VertexType; //定义图 的邻接矩阵表示法结构 typedef struct Graph { VertexType ver[MaxSize+1];// 顶点表,是一位数组 int edg[MaxSize][MaxSize];// 邻接矩阵,可以看做是边表 }Graph; //邻接矩阵法图的生成函数 void CreateGraph( Graph *g ){ int i = 0; int j = 0; int VertexNum; VertexType Ver; while( ' ' != (Ver=getchar()) ) g->ver[i++] = Ver; g->ver[i] = '