通过对图的最短路径,我们有迪杰斯特拉和弗洛伊德算法,二者各有好处,当迪杰斯特拉算法
可以通过求一个顶点到各个顶点最短路径,而弗洛伊德算法可以更加清晰求出各点之间的路径
通过不同代码可以展示不同结果
代码如下:
#include<stdio.h>
#include<iostream>
#include<malloc.h>
using namespace std;
//构建无向网
#define MVNum 100//设置最大顶点数为100自定义宏
#define INFINITY 35575//定义宏数字35575代表无穷大
//bool visted[MVNum];
typedef char Vertextype;
typedef int edge;
//无向网图的建立
typedef struct
{
Vertextype vex[MVNum];//一维数组储存顶点,依次存储每个顶点构建邻接矩阵
edge arcs[MVNum][MVNum];//二维数组邻接矩阵
int vexnum, arcnum;
}DK;//零阶矩阵的存储表示
typedef int parch[MVNum];//储存最短路径下标的数组
typedef int shortestsum[MVNum];
//{
// cout << "输入顶点";
// cin >> u;
// int i;
// for (i = 0; i < G.vexnum; i++)
// {
// if (u == G.vex[i])
// {
//
// return i;
// }
// return -1;
// }
//}
void CreatUDN(DK& G)//表示通过G带回返回值
{
cout << "请输入顶点数和边数 :";
cin >> G.vexnum >> G.arcnum;
int i, j, k, w;
//Vertextype v1, v2;
cout << "存入顶点";
for (i = 0; i < G.vexnum; i++)
{
cin >> G.vex[i];
}
for (i = 0; i < G.vexnum; i++)
{
for (j = 0; j < G.vexnum; j++)
{
G.arcs[i][j] = INFINITY;
}
}
/*for (i = 0; i < G.vexnum; i++)
{
for (j = 0; j < G.vexnum; j++)
{
G.arcs[0][0] = 0;
if (i = j)
{
G.arcs[i][j] = 0;
}
}
}*/
//初始化各顶点
//for (int i = 0; i < G.vexnum; i++)
//{
// printf("\n");
// for (int j = 0; j < G.vexnum; j++)
// {
// //cout << G.arcs[i][j];
// printf("%d\t", G.arcs[i][j]);
// //测试是否初始化成功
// }
//}
for (k = 0; k < G.arcnum; k++)
{
int g_i, g_j;
cout << "输入参数和权值:";
cin >> g_i >> g_j;
cin >> w;
G.arcs[g_i][g_j] = w;//由于g_i和g_j从零开始所以记得对应位置-1
G.arcs[g_j][g_i] = G.arcs[g_i][g_j];
//cout << "输入顶点和权值";
//cin >> v1 >> v2>>w;
//i = Localvex(v1, G);//调用函数返回v1在表中位置
//j = Localvex(v2, G);
//G.arcs[i][j] = w;
//G.arcs[j][i] = w;//无向网图为对称矩阵
}
}
//构建邻接矩阵矩阵
void Print(DK& G)
{
for (int j = 0; j < G.vexnum; j++)
{
printf("\n");
for (int i = 0; i < G.vexnum; i++)
{
//cout << G.arcs[i][j];
printf("%d\t", G.arcs[i][j]);
}
cout << endl;
}
}
void Dijkstra(DK &G,int v,int P[MVNum], int S[MVNum])
{
int now_short[MVNum] = {0};
int i, j, k, min,f;
int v0;
for (i = 0; i < G.vexnum; i++)
{
now_short[i]=0;//0 1代表是否求得最短路径,0为否,1为是
S[i] =G.arcs[v][i] ;//记录权值
P[i] = 0;
}
S[v] = 0;
now_short[v] = 1;
cout <<G.vex[ v]<<endl;
for (j = 1; j < G.vexnum; j++)
{
min = INFINITY;
for (k = 0; k < G.vexnum; k++)//寻找与v最近的顶点
{
if (!now_short[k] && S[k] < min)
{
min = S[k];
f = k;//记录最近顶点的下标
}
}
now_short[f] = 1;
for (k = 0; k < G.vexnum; k++)
{
if (!now_short[k] && (G.arcs[f][k] + min< S[k]))
{
S[k] = G.arcs[f][k] + min;
P[k] = f;//存入前驱顶点的下标
}
}//将与前一个顶点相连的权值存入S[]数组
}
for (i = 0; i < G.vexnum; i++)
{
cout << G.vex[v] << G.vex[i] << S[i] << endl;
}//输出该点到每个点的路径和距离
}
void Floyd(DK G,int P[MVNum][MVNum],int S[MVNum][MVNum])
{
int i, j;
int w, y,z;
for (i = 0; i < G.vexnum; i++)
{
for (j = 0; j < G.vexnum; j++)
{
S[i][j] = G.arcs[i][j];
P[i][j] = j;
}
}
for (w = 0; w < G.vexnum; w++)//中转点下标
{
for (y = 0; y < G.vexnum; y++)//起始点下标
{
for (z = 0; z < G.vexnum; z++)//结束点下标
{
if (S[y][z] > S[y][w] + S[w][z]&&y!=z)
{
S[y][z] = S[y][w] + S[w][z];
P[y][z] = P[y][w];//更新前驱节点
}
}//将每个点作为中转点带入矩阵遍历
}
}
for (i = 0; i < G.vexnum;i++)
{
for (j = 0; j < G.vexnum; j++)
{
printf("%d\t", P[i][j]);
}
cout << endl;
}
}
int main(void)
{
DK TESTdk;
CreatUDN(TESTdk);
Print(TESTdk);
int parchs[MVNum];//储存最短路径下标的数组
int shortestsums[MVNum];//储存最小权值和
int parchfy[MVNum][MVNum];
int nums[MVNum][MVNum];
Dijkstra(TESTdk,0,parchs,shortestsums);
Floyd(TESTdk,parchfy,nums);
return 0;
}