求最短路径的第二种算法Floyd算法,前一个算法Dijkstra的时间复杂度是O(n3)
这个算法的时间复杂度也是O(n3),不过这个算法更加精妙。
其基本思想:我们从任意节点A到任意节点B的最短距离不外乎2种可能,1是直接A到B,2是从A经过若干个节点X后到B。
我们假设Dis(AB)为节点A到节点B的最短路径距离,那么我们要做的事就是检查Dis(AX)+Dis(XB)是否小于Dis(AB),如果小于则将Dis(AB)=Dis(AX)+Dis(XB),再次遍历,遍历完所有的X节点之后,得到的Dis(AB)就是最短路径的距离。
那下面就是实现过程,图的结构仍然使用的是邻接矩阵的形式。
我们对上述Dis(AX)求解的时候,我们应该首先计算靠外的部分,而不应该先计算内部,如果先计算内部,则会出现外部的距离很短却不知道的情况。
这样我们对于每一个点X,我们都先计算出所有的i到j之后再检查下一个节点,这样就不会有遗漏的情况。
好,下面我们要给出最短路径的话,我们就要添加一个辅助数组path,这个path数组中给出A到B的路径经过路径,比如A->D,经过B,C,路径是A->B->C->D,则path存储的是P(AD)=B,P(AD)=C,P(CD)=D
好,那下面给出代码:
#include <stdio.h> #define MAXVEX 9 #define INFINITY 65535 //定义一个图结构 typedef struct MGraph { char vexs[MAXVEX]; int arc[MAXVEX][MAXVEX]; int numVertexes,numEdges; }MGraph; void createMGraph(MGraph *g); void shortPathFloyd(MGraph g,int p[][MAXVEX],int s[][MAXVEX]); void createMGraph(MGraph *g) { int i,j; g->numEdges=16; g->numVertexes=9; for(i=0;i<MAXVEX;i++) { g->vexs[i]=i; } for(i=0;i<g->numVertexes;i++) { for(j=0;j<g->numVertexes;j++) { if(i==j) { g->arc[i][j]=0; } else { g->arc[i][j]=g->arc[j][i]=INFINITY; } } } g->arc[0][1]=1; g->arc[0][2]=5; g->arc[1][2]=3; g->arc[1][3]=7; g->arc[1][4]=5; g->arc[2][4]=1; g->arc[2][5]=7; g->arc[3][4]=2; g->arc[3][6]=3; g->arc[4][5]=3; g->arc[4][6]=6; g->arc[4][7]=9; g->arc[5][7]=5; g->arc[6][7]=2; g->arc[6][8]=7; g->arc[7][8]=4; for(i=0;i<g->numVertexes;i++) { for(j=i;j<g->numVertexes;j++) { g->arc[j][i] =g->arc[i][j]; } } } void shortPathFloyd(MGraph g,int p[][MAXVEX],int s[][MAXVEX]) { int i,j,k; for(i=0;i<g.numVertexes;i++) { for(j=0;j<g.numVertexes;j++) { s[i][j]=g.arc[i][j]; p[i][j]=j; } } for(k=0;k<g.numVertexes;k++) { for(i=0;i<g.numVertexes;i++) { for(j=0;j<g.numVertexes;j++) { if(s[i][j]>s[i][k]+s[k][j]) { s[i][j]=s[i][k]+s[k][j]; p[i][j]=p[i][k]; } } } } } int main() { MGraph g; int i,j,k; int patharc[MAXVEX][MAXVEX],shortPath[MAXVEX][MAXVEX]; createMGraph(&g); shortPathFloyd(g,patharc,shortPath); for(i=0;i<g.numVertexes;i++) { for(j=i+1;j<g.numVertexes;j++) { printf("v%d-v%d weight: %d ",i,j,shortPath[i][j]); k=patharc[i][j]; printf(" path: %d",i); while(k!=j) { printf(" -> %d",k); k=patharc[k][j]; } printf(" -> %d ",j); } printf(" "); } return 0; }