C语言实现迪杰斯特拉算法详解
创作时间:
作者:
@小白创作中心
C语言实现迪杰斯特拉算法详解
引用
CSDN
1.
https://blog.csdn.net/ZGUIZ/article/details/54645019
迪杰斯特拉算法(Dijkstra算法)是用于求解图中单源最短路径的经典算法。它广泛应用于网络路由、地图导航等领域。本文将通过C语言实现,详细讲解迪杰斯特拉算法的原理和实现步骤。
1. 数据结构定义
首先,我们需要定义一些基本的数据结构和常量:
#define OK 1
#define ERROR 0
#define MVNum 100
#define Max_Int 32726
typedef int Status;
typedef int ArcType;
typedef char VerTexType;
typedef struct{
VerTexType vex[MVNum];
ArcType arc[MVNum][MVNum];
int vexnum, arcnum;
}AMGraph;
这里定义了一个邻接矩阵表示的图结构AMGraph
,其中vex
数组存储顶点信息,arc
数组存储边的权值,vexnum
和arcnum
分别表示顶点数和边数。
2. 全局变量声明
我们还需要两个全局变量来辅助算法的实现:
int Path[MVNum];
ArcType D[MVNum];
Path[]
用于记录到达每个顶点的上一个顶点。D[]
用于记录从源点到每个顶点的最短路径的权值。
3. 图的创建函数
接下来是创建有向图的函数:
int LocateVex(AMGraph *G, VerTexType v)
{
int i;
for (i = 0; i < G->vexnum; i++)
{
if (G->vex[i] == v)
return i;
}
return -1;
}
Status CreateUDN(AMGraph *G)
{
VerTexType v1, v2;
ArcType w;
int i, j, k;
printf("输入总节点数、总边数:");
scanf("%d %d", &G->vexnum, &G->arcnum);
printf("输入节点的值:");
fflush(stdin);
for (i = 0; i < G->vexnum; i++)
{
scanf("%c", &G->vex[i]);
}
for (i = 0; i < G->vexnum; i++)
for (j = 0; j < G->vexnum; j++)
{
G->arc[i][j] = Max_Int;
}
for (k = 0; k < G->arcnum; k++)
{
fflush(stdin);
printf("依次输入边的两个顶点以及边的权值:");
scanf("%c %c %d", &v1, &v2, &w);
i = LocateVex(G, v1);
j = LocateVex(G, v2);
G->arc[i][j] = w;
}
return OK;
}
这个函数首先读取图的顶点数和边数,然后依次读取每个顶点的值,初始化邻接矩阵,并读取每条边的两个顶点和权值。
4. 迪杰斯特拉算法实现
核心算法实现如下:
void ShortestPath_DIJ(AMGraph G, int v0)
{
int min, i, w, v;
bool S[MVNum];
for (v = 0; v < G.vexnum; v++)
{
S[v] = false;
D[v] = G.arc[v0][v];
if (D[v] < Max_Int)
Path[v] = 0;
else
Path[v] = -1;
}
S[v0] = true;
D[v0] = 0;
for (i = 1; i < G.vexnum; i++)
{
min = Max_Int;
for (w = 0; w < G.vexnum; w++)
{
if (!S[w] && min>D[w])
{
v = w;
min = D[w];
}
}
S[v] = true;
for (w = 0; w < G.vexnum; w++)
{
if (!S[w] && D[w]>D[v] + G.arc[v][w])
{
D[w] = D[v] + G.arc[v][w];
Path[w] = v;
}
}
}
}
算法的主要步骤包括:
- 初始化:将所有顶点标记为未访问,将源点到其他顶点的初始距离设置为邻接矩阵中的值,如果存在边则设置为边的权值,否则设置为无穷大。
- 选择当前未访问顶点中距离源点最近的顶点,标记为已访问。
- 更新从源点到其他未访问顶点的距离,如果通过当前顶点可以得到更短的路径,则更新距离和路径信息。
- 重复步骤2和3,直到所有顶点都被访问。
5. 主函数
最后是主函数的实现:
int main(void)
{
int i, j;
AMGraph G;
CreateUDN(&G);
ShortestPath_DIJ(G, 0);
for (i = 1; i < G.vexnum; i++)
{
if (D[i] == Max_Int)
printf("0无法到达%c\n", G.vex[i]);
else
printf("0到%c的权值为:%d\n", G.vex[i], D[i]);
}
return 0;
}
主函数首先创建图,然后调用迪杰斯特拉算法计算从顶点0到其他所有顶点的最短路径,并输出结果。
总结
迪杰斯特拉算法通过维护一个已确定最短路径的顶点集合和一个未确定最短路径的顶点集合,逐步更新最短路径信息,最终得到从源点到所有其他顶点的最短路径。这个算法在实际应用中非常广泛,例如在网络路由、地图导航等领域都有重要的应用价值。
热门推荐
总监助理如何管理团队
胃嗳气的有效治愈方法有什么
产品经理如何在外企招聘中脱颖而出
气虚的女人夏天喝什么茶好呢?适合泡茶与水的食材全解析
温度控制:精酿啤酒发酵中的关键因素
什么蔬菜高产又好种?
【21天学会AutoCAD】第2天:绘制倾斜直线
胖猫事件发酵,国服梦奇更换头像!王者玩家集体悼念
1岁多宝宝晚上睡觉不踏实易醒易哭闹的原因和处理
生菜的种植环境与条件(生长地方)
如何有效更新打印机驱动程序,保持设备最佳工作状态的技巧与方法
肺含气囊肿的分类、定义及CT诊断思维
景德镇特色小吃:四大小吃与地道美食全攻略
天然气利用管理办法时隔12年再修订:油气股走强,修订释放哪些信号?
油颗粒度测定仪测量准确性怎么确定?
如何通过外部前置放大器的ADAT输出端口与Focusrite声卡连接并实现同步?
星座可信吗?有科学依据吗?
客户成功如何做好续约管理
困在“劳动供养率”里的年轻人
故障分析报告怎么写?故障分析报告的作用与步骤详解,故障分析报告的应用场景
脂膜炎做什么检查可以准确判定病因
阑尾切除术是什么
贝因美公告不细心,控股股东“不省心”,盈亏交替欲再砸8000万元投建新项目
现实人生是文学研究的出发点与归宿
越婢汤的组成以及功效
潍坊市妇幼保健院先后引进两种新型生物制剂精准治疗幼年特发性关节炎
北京地铁昌平线南延一期最新消息:5座新站开通,换乘更便捷
转弯未让直行酿事故,安全驾驶切莫大意!
玻璃棉是如何做到吸声隔音降噪的?
耳朵发炎可以吃布洛芬缓释胶囊吗