其实Dijkstra是单源点最短路径的基础算法,这个算法的目的就是找到一个图中的某个点V到这个图中其他点的最短路径。
时间复杂度:O(E) + O(V^2) = O(V^2)
当图是稠密的时候和稀疏的时候时间复杂度还是有点差别的。
其实这个还挺简单的,单源点最短路径还有一个Bellman-Ford算法,以后在写,比较简单。
Dijkstra算法:
//
// main.cpp
// Dijkstra
//
// Created by Alps on 15/3/4.
// Copyright (c) 2015年 chen. All rights reserved.
//
#include <iostream>
#ifndef NumVertex
#define NumVertex 4 //定义图的顶点数量
#endif
#ifndef Infinity
#define Infinity 10000 //定义权值最大值
#endif
using namespace std;
typedef int Vertex;
struct LinkList{ //定义邻接链表
int val;
int length;
LinkList * next;
LinkList(int v): val(v), next(NULL) {}
};
typedef LinkList* List;
struct TableEntry{ //定义结构体用来实现算法。
List Header;
bool Know;
int Dist;
Vertex Path;
};
typedef struct TableEntry Table[NumVertex+1]; //定义结构体所存储的图
void InitTable(Vertex Start, Table T){ //初始化
List temp;
int OutDegree;
for (int i = 1; i <= NumVertex; i++) {
T[i].Know = false;
T[i].Dist = Infinity;
T[i].Path = -1;
T[i].Header = NULL;
scanf("%d",&OutDegree);
for (int j = 0; j < OutDegree; j++) {
temp = (List)malloc(sizeof(struct LinkList));
scanf("%d %d",&(temp->val), &(temp->length));
temp->next = T[i].Header;
T[i].Header = temp;
}
}
T[Start].Dist = 0;
}
void PrintPath (Vertex V,Table T){ //打印路径
if (T[V].Path != -1) {
PrintPath(T[V].Path, T);
printf(" to ");
}
printf("%d", V);
}
Vertex SmallDistUnknow(Table T){ //查找当前已知顶点到未知顶点路径的最小值
int MinDist = Infinity + 1, V = 0;
for (int i = 1; i <= NumVertex; i++) {
if (!T[i].Know && T[i].Dist <= MinDist) {
MinDist = T[i].Dist;
V = i;
}
}
return V;
}
void Dijkstra(Table T){ //算法主题
List temp;
Vertex V;
while (1) {
V = SmallDistUnknow(T);
if (V == 0) {
break;
}
T[V].Know = true;
temp = T[V].Header;
while (temp != NULL) {
if (!T[temp->val].Know) {
if (T[V].Dist + temp->length < T[temp->val].Dist) {
T[temp->val].Dist = T[V].Dist + temp->length;
T[temp->val].Path = V;
}
}
temp = temp->next;
}
}
}
int main(int argc, const char * argv[]) {
Table T;
InitTable(1, T);
Dijkstra(T);
PrintPath(2, T);
// std::cout << "Hello, World!\n";
return 0;
}
原文地址:http://blog.csdn.net/alps1992/article/details/44196437