1、最短路路径-Dijkstra 算法
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXEDGE 20
#define MAXVEX 20
#define INFINITYC 65535
typedef int Status;
typedef struct {
int vexs[MAXVEX];
int arc[MAXVEX][MAXVEX];
int numVertexes, numEdges;
}MGraph;
typedef int Patharc[MAXVEX][MAXVEX];
typedef int ShortPathTable[MAXVEX][MAXVEX];
/* 求得网图中2点间最短路径
Dijkstra 算法
G: 网图;
v0: V0开始的顶点;
p[v]: 前驱顶点下标;
D[v]: 表示从V0到V的最短路径长度和;
*/
void ShortestPath_Dijkstra(MGraph G, int v0, Patharc *P, ShortPathTable *D)
{
int v, w, k, min;
k = 0;
/*final[w] = 1 表示求得顶点V0~Vw的最短路径*/
int final[MAXVEX];
/*1.初始化数据*/
for (v = 0; v < G.numVertexes; v++) {
//全部顶点初始化为未知最短路径状态0
final[v] = 0;
//将与V0 点有连线的顶点最短路径值;
(*D)[v] = G.arc[v0][v];
//初始化路径数组p = 0;
(*P)[v] = 0;
}
//V0到V0的路径为0
(*D)[v0] = 0;
//V0到V0 是没有路径的.
final[v0] = 1;
//v0到V0是没有路径的
(*P)[v0] = -1;
//2. 开始主循环,每次求得V0到某个顶点的最短路径
for (v = 1; v < G.numVertexes; v++) {
//当前所知距离V0顶点最近的距离
min = INFINITYC;
/*3.寻找离V0最近的顶点*/
for (w = 0; w < G.numVertexes; w++) {
if (!final[w] && (*D)[w] < min) {
k = w;
//w顶点距离V0顶点更近
min = (*D)[w];
}
}
//将目前找到最近的顶点置为1;
final[k] = 1;
/*4.把刚刚找到v0到v1最短路径的基础上,对于v1 与 其他顶点的边进行计算,得到v0与它们的当前最短距离;*/
for (w = 0; w < G.numVertexes; w++) {
//如果经过v顶点的路径比现在这条路径长度短,则更新
if (!final[w] && (min + G.arc[k][w] < (*D)[w])) {
//找到更短路径, 则修改D[W],P[W]
//修改当前路径的长度
(*D)[w] = min + G.arc[k][w];
(*P)[w] = k;
}
}
}
}
swift
struct MGraph {
var arc: Array<Array<Int>> = Array<Array<Int>>()
var numNodes: Int = 0, numEdges: Int = 0
/* 2 求得网图中2点间最短路径
Dijkstra 算法
G: 网图;
v0: V0开始的顶点;
p[v]: 前驱顶点下标;
D[v]: 表示从V0到V的最短路径长度和;
*/
func shortestPath_Dijkstra(_ v: Int) -> (Array<Int>, Array<Int>) {
// 1 初始化路径数组p = 0;
var p = Array<Int>(repeating: 0, count: numNodes)
// 将与V 点有连线的顶点最短路径值;
var d = arc[v]
/* final[w] = 1 表示求得顶点V0~Vw的最短路径 */
var final = Array<Int>(repeating: 0, count: numNodes)
// V到V的路径为0
d[v] = 0
// V到V 是没有路径的.
final[v] = 1
// v0到V0是没有路径的
p[v] = -1
var k = 0
// 2. 开始主循环,每次求得V0到某个顶点的最短路径
for _ in 0 ..< numNodes {
// 当前所知距离V0顶点最近的距离
var min = Int.max
/* 3.寻找离V最近的顶点 */
for j in 0 ..< numNodes {
if final[j] == 0 && d[j] < min {
k = j
min = d[j]
}
}
// 将目前找到最近的顶点置为1;
final[k] = 1
/* 4.把刚刚找到v0到v1最短路径的基础上,对于v1 与 其他顶点的边进行计算,得到v0与它们的当前最短距离; */
for j in 0 ..< numNodes {
// 如果经过v顶点的路径比现在这条路径长度短,则更新
if final[j] == 0 && (min < Int.max && arc[k][j] < Int.max && min + arc[k][j] < d[j]) {
// 找到更短路径, 则修改D[j],P[j]
// 修改当前路径的长度
d[j] = min + arc[k][j]
p[j] = k
}
}
}
return (p, d)
}
}
2、最短路径Floyd算法
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXEDGE 20
#define MAXVEX 20
#define INFINITYC 65535
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef struct {
int vexs[MAXVEX];
int arc[MAXVEX][MAXVEX];
int numVertexes, numEdges;
}MGraph;
typedef int Patharc[MAXVEX][MAXVEX];
typedef int ShortPathTable[MAXVEX][MAXVEX];
/*
Floyd算法,求网图G中各顶点v到其余顶点w的最短路径P[v][w]及带权长度D[v][w]。
Patharc 和 ShortPathTable 都是二维数组;
*/
void ShortestPath_Floyd(MGraph G, Patharc *P, ShortPathTable *D) {
int v, w, k;
/* 1. 初始化D与P 矩阵*/
for (v = 0; v < G.numVertexes; ++v) {
for (w = 0; w < G.numVertexes; ++w) {
/* D[v][w]值即为对应点间的权值 */
(*D)[v][w] = G.arc[v][w];
/* 初始化P P[v][w] = w*/
(*P)[v][w] = w;
}
}
//2.K表示经过的中转顶点
for (k = 0; k < G.numVertexes; ++k) {
for (v = 0; v < G.numVertexes; ++v) {
for (w = 0; w < G.numVertexes; ++w) {
/*如果经过下标为k顶点路径比原两点间路径更短 */
if ((*D)[v][w] > (*D)[v][k] + (*D)[k][w]) {
/* 将当前两点间权值设为更小的一个 */
(*D)[v][w] = (*D)[v][k] + (*D)[k][w];
/* 路径设置为经过下标为k的顶点 */
(*P)[v][w] = (*P)[v][k];
}
}
}
}
}
swift
struct MGraph {
var arc: Array<Array<Int>> = Array<Array<Int>>()
var numNodes: Int = 0, numEdges: Int = 0
/*
Floyd算法,求网图G中各顶点v到其余顶点w的最短路径P[v][w]及带权长度D[v][w]。
Patharc 和 ShortPathTable 都是二维数组;
*/
func shortestPath_Floyd() -> (Array<Array<Int>>, Array<Array<Int>>) {
var p = Array<Array<Int>>()
var d = Array<Array<Int>>()
/* 1. 初始化D与P 矩阵*/
for v in 0 ..< numNodes {
var pv = Array<Int>()
var dv = Array<Int>()
for w in 0 ..< numNodes {
/* D[v][w]值即为对应点间的权值 */
dv.append(arc[v][w])
/* 初始化P P[v][w] = w*/
pv.append(w)
}
p.append(pv)
d.append(dv)
}
// 2.K表示经过的中转顶点
for k in 0 ..< numNodes {
for v in 0 ..< numNodes {
for w in 0 ..< numNodes {
/* 如果经过下标为k顶点路径比原两点间路径更短 */
if d[v][k] < Int.max && d[k][w] < Int.max && d[v][w] > d[v][k] + d[k][w] {
/* 将当前两点间权值设为更小的一个 */
d[v][w] = d[v][k] + d[k][w]
/* 路径设置为经过下标为k的顶点 */
p[v][w] = p[v][k]
}
}
}
}
return (p, d)
}
}