迪杰斯特拉算法的核心就是找到源节点然后在有向图中找到以这个结点为起始结点的边的终止结点,比较这个终止结点的距离和其实结点的距离加上这条边的权值进行比较,然后做完这些操作之后就再这里写结点中找到未被选择的结点的最小值加入select集合中再将这个结点看作源结点再次递归,当选了n个结点的时候退出循环,所有的distant即为所要的值。
dijkstr的时间复杂度为O(n^2)
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<string.h>
typedef struct vertex {
bool select;
int distant;
}vertex;
vertex *vertexs;
int **graph;
int vertex_number;
int edge_number;
int begin;
int signselect;
void init() {
signselect = 0;
printf("请输入源结点");
scanf("%d", &begin);
printf("请输入结点数");
scanf("%d", &vertex_number);
printf("请输入有向边的数");
scanf("%d", &edge_number);
vertexs = (vertex*)malloc(sizeof(vertex) * vertex_number);
graph = (int**)malloc(sizeof(int*) * vertex_number);
for (int i = 0; i < vertex_number; ++i) {
graph[i] = (int*)malloc(sizeof(int) * vertex_number);
for (int j = 0; j < vertex_number; ++j) {
graph[i][j] = 0;
}
}
for (int i = 0; i < edge_number; ++i) {
int x, y;
printf("请输入第一个点");
scanf("%d", &x);
printf("请输入第二个点");
scanf("%d", &y);
printf("请输入边的值");
scanf("%d", &graph[x][y]);
}
for (int i = 0; i < vertex_number; ++i) {
vertexs[i].select = false;
vertexs[i].distant = INT_MAX;
}
vertexs[begin].distant = 0;
}
void dijkstra(int n) {
if (signselect == vertex_number - 1) {
return;
}
vertexs[n].select = true;
for (int i = 0; i < vertex_number; ++i) {
if (graph[n][i] && i != n) {
if (graph[n][i] + vertexs[n].distant < vertexs[i].distant) {
vertexs[i].distant = graph[n][i] + vertexs[n].distant;
}
}
}
int mindistant = INT_MAX;
int signvertex;
for (int i = 0; i < vertex_number; ++i) {
if (!vertexs[i].select) {
if (mindistant > vertexs[i].distant) {
signvertex = i;
mindistant = vertexs[i].distant;
}
}
}
signselect++;
dijkstra(signvertex);
}
void show() {
for (int i = 0; i < vertex_number; ++i) {
printf("第%d个点的最小值为%d\n", i, vertexs[i].distant);
}
}
int main() {
init();
dijkstra(begin);
show();
return 0;
}