单源最短路径(堆优化的Dijkstra算法)

来源:互联网 发布:vb6.0连接mysql数据库 编辑:程序博客网 时间:2024/05/16 19:54

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 65535typedef 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);}
0 0
原创粉丝点击