路由算法Dijkstra
迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻接节点,直到扩展到终点为止。
Dijkstra算法一般的表述通常有两种方式,一种用永久和临时标号方式,一种是用OPEN, CLOSE表的方式,这里均采用永久和临时标号的方式。注意该算法要求图中不存在负权边。
自己记录一下,该代码已在vs中验证。
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#define N 100 /*节点最大个数*/
#define INF 1e7 /*初始化无穷大为*/
int dist[N], p[N], n, m; /*n为节点个数,m为节点间路线的条数*/
bool flag[N]; /*如果flag[i]=true,说明该顶点i已经加入到集合S;否则i属于集合V-S*/
int route_map[N][N] = { {0,0, 0, 0, 0, 0, 0 },
{0,0xff,3, 10, 0xff,30, 100 },
{0,3, 0xff,5, 0xff,0xff,0xff},
{0,10, 0xff,0xff,50, 0xff,0xff},
{0,0xff,0xff,50, 0xff,0xff,10 },
{0,30, 0xff,0xff,20, 0xff,60 },
{0,0xff,0xff,0xff,0xff,0xff,0xff} }; /*带权值的二维图*/
/* 迪杰斯特拉算法,u 表示当前节点 */
void Dijkstra(int u)
{
for (int i = 1; i <= n; i++) /********>>>--1--<<<*******/
{
dist[i] = route_map[u][i]; /*初始化源点u到其他各个顶点的最短路径长度*/
flag[i] = false;
if (dist[i] == INF)
p[i] = -1; /*说明源点u到顶点i无边相连,设置p[i]=-1*/
else
p[i] = u; /*说明源点u到顶点i有边相连,设置p[i]=u*/
}
flag[u] = true; /*初始化集合S中,只有一个元素:源点u*/
dist[u] = 0; /*初始化源点u的最短路径为0,自己到自己的最短路径*/
for (int i = 1; i <= n; i++) /********>>>--2--<<<*******/
{
int temp = INF, t = u;
for (int j = 1; j <= n; j++) /********>>>--3--<<<********/
{
if (!flag[j] && dist[j] < temp) /*在集合V-S中寻找距离源点u最近的顶点t*/
{
t = j; /*记录距离源点u最近的顶点*/
temp = dist[j];
}
}
if (t == u) return; /*找不到t跳出循环*/
flag[t] = true; /*否则,将t加入集合S*/
for (int j = 1; j <= n; j++) /*>>--4--<<更新集合V-S中与t邻接的顶点到u的距离*/
{
if (!flag[j] && route_map[t][j] < INF) /*!flag[j]表示j在v-s集合中,route_map[t][j]<INF表示t与j邻接*/
{
if (dist[j] > (dist[t] + route_map[t][j])) /*经过t到达j的路径更短*/
{
dist[j] = dist[t] + route_map[t][j];
p[j] = t; /*记录j的前驱为t*/
}
}
}
}
}
int main() {
int u, v, w, st;
n = 6; /*设置节点数为6个节点*/
st = 1; /*设置当前节点地址为1*/
Dijkstra(st);
printf("当前节点所在的位置:%d\n",st);
for (int i = 1; i <= n; i++)
{
printf("当前节点:%d --要去的位置:%d",st,i);
if (dist[i] == INF)
printf("sorry,无路可达\n");
else
printf("最短距离为: %d\n", dist[i]);
}
return 0;
}