Dijkstra算法:设初始节点为v,起始节点到其他节点u的距离为图中v到u的直接线路的距离,如果v和u之间没有直接线路,则d[u]=INF(无穷大)。初始化S={v},寻找最短路径(即在d[]中寻找使d[u]最小的u),将u加入到S中,然后更改到u节点可到达节点的最小距离。再寻找次短路径,并将次短路径的目标节点(设为u)加入到S中,更改到u节点可到达节点的最小距离.如此下去,知道S=V.
一般的Dijkstra算法每次寻找最短路径的时间复杂度O(n),整个算法的时间复杂度为O(n^2).带堆优化的Dijkstra算法每次寻找最短路径时采用堆排序,时间复杂度O(logn)。整个算法的时间复杂度为O(n*logn).
#include<stdio.h>
#include<malloc.h>
#define INF 65535
typedef struct ArcNode{
int dst;
int value;
struct ArcNode *nextarc;
}ArcNode;
typedef struct VNode{
int data;
ArcNode * firstedge;
}VNode;
void createAdjList(VNode *&L,int n,int m);
void Dijkstra(int *&d,VNode *&L,int n);
void HeapSort(int *&d,int *&dsti,int n);
void remove(VNode *&L,ArcNode *s);
void removeAdjList(VNode *&L,int n);
int main()
{
int n,m,i;
scanf("%d%d",&n,&m);
VNode *L;
createAdjList(L,n,m);
int *d=(int *)malloc(sizeof(int)*n);
Dijkstra(d,L,n);
for(i=1;i<n;i++)
printf("%d\n",d[i]);
removeAdjList(L,n);
free(d);
return 0;
}
//创建有向图的邻接表
void createAdjList(VNode *&L,int n,int m)
{
int i,u,v,l;
L=(VNode *)malloc(sizeof(VNode)*n);
for(i=0;i<n;i++)
{
L[i].data=i;
L[i].firstedge=NULL;
}
for(i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&l);
ArcNode *s=(ArcNode *)malloc(sizeof(ArcNode));
s->dst=v;s->nextarc=NULL;s->value=l;
if(!L[u].firstedge)
L[u].firstedge=s;
else
{
ArcNode *t=L[u].firstedge;
while(t->nextarc)
t=t->nextarc;
t->nextarc=s;
}
}
}
//带堆优化的Dijkstra算法
void Dijkstra(int *&d,VNode *&L,int n)
{
int i;
//dsti存放到各目标顶点的编号
int * dsti=(int *)malloc(sizeof(int)*n);
for(i=0;i<n;i++)
{
dsti[i]=i;
d[i]=INF;
}
//初始化到各点的距离
d[0]=0;
ArcNode *t=L[0].firstedge;
while(t)
{
d[t->dst]=t->value;
t=t->nextarc;
}
for(i=n-1;i>=2;i--)
{
HeapSort(d,dsti,i);
ArcNode *s=L[dsti[1]].firstedge;
while(s)
{
if(d[s->dst]>d[dsti[1]]+s->value)
d[s->dst]=d[dsti[1]]+s->value;
s=s->nextarc;
}
int temp=dsti[1];
dsti[1]=dsti[i];
dsti[i]=temp;
}
}
//堆排序——最小堆,n为参与堆排序的元素的个数
void HeapSort(int *&d,int *&dsti,int n)
{
int i,j;
for(i=n/2;i>=1;i--)
{
int num=dsti[i];
for(j=i*2;j<=n;j=j*2)
{
if(j+1<=n&&d[dsti[j]]>d[dsti[j+1]])
j++;
if(d[dsti[j]]>d[num])
break;
dsti[j/2]=dsti[j];
}
dsti[j/2]=num;
}
}
//释放一行邻接表所占空间
void remove(VNode *&L,ArcNode *s)
{
if(!s)
return ;
while(s)
{
remove(L,s->nextarc);
}
free(s);
}
//删除整个邻接表所占空间
void removeAdjList(VNode *&L,int n)
{
int i;
for(i=0;i<n;i++)
{
ArcNode *s=L[i].firstedge;
remove(L,s);
}
free(L);
}