最小生成树:
//prim算法 Status MiniSpanTree_Prim(MGraph G,VertexType u) { typedef struct{ VertexType adjvex; int lowcost; }closedge[MAX_VERTEXNUM]; int minivex(closedge);//求出closedge中lowcost最小节点,返回其在数组中序号 k=Locate(G,u);//找出节点u在节点数组的位置 for(j=0;j<G.vexnum;++j) if(j!=k&&G.arcs[k][j].adj)//辅助数组初始化 { closedge[j].adjvex=u; closedge[j].lowcost=G.arcs[k][j].adj; } closedge[k].lowcost=0;//已访问的节点置于u集中 for(i=1;i<G.vexnum;++i)//选择其余G.vexnum-1个顶点 { k=minivex(closedge,G);//求出T的下一个顶点:第k顶点 printf(closedge[k].adjvex->G.vex[k]);//输出生成树的边 closedge[k].lowcost=0;//第k顶点并入u集 for(j=0;j<G.vexnum;++j)//加入G.vex[k]后有边权值比原来小 if(G.arcs[k][j].adj>0&&G.arcs[k][j].adj<closedge[j].lowcost) { closedge[j].adjvex=G.vex[k]; closedge[j].lowcost=G.arcs[k][j].adj; } } }
//kruskal算法 Status MiniSpanTree_Kruskal(MGraph G) { int set[MAX_VERTEX_NUM],i,j; int k=0,a=0,b=0,min=G.arcs[a][b].adj; for(i=0;i<G.vexnum;++i) set[i]=i;//初态,各顶点分别属于各集合 while(k<G.vexnum-1)//最小生成树边数小于顶点树减1 {//寻找最小权值的边 for(i=0;i<G.vexnum;++i) for(j=i+1;j<G.vexnum;++j) if(G.arc[i][j]<min) { min=G.arcs[i][j]; a=i;b=j; } min=G.arcs[a][b].adj=INFINITY;//删除上三角中该边,下次不再查找 if(set[a]!=set[b])//边的两顶点不属于同一集合 { printf(G.vexs[a]-G.vexs[b]);//输出该边 k++;//边数加一 for(i=0;i<G.vexnum;i++) if(set[i]==set[b]) set[i]=set[a]; } } }
最短路径:dijstra,floyd
//dijstra Status ShortestPath_Dijstra(Graph G,int v0,pathmatrix p,shortpathtable d) { int v,w,i,j,min; Status final[];//为真表示该顶点到v0最短距离已求出,初值为假 for(v=0;v<G.vexnum;v++) { final[v]=FALSE; d[v]=G.arcs[v0][v].adj;//d[]存放v0到v的最短距离,初值为直接距离 for(w=0;w<G.vexnum;+=w) p[v][w]=FALSE;//初值为FALSE,表示没有路径 if(d[v]<INFINITY)//v0到v有直接路径 p[v][v0]=p[v][v]=TRUE;//一维数组p[v][]表示v0到v最短路径通过的顶点 }//initial,v0 belongs to Set[s] d[v0]=0;//v0到v0距离为0 final[v0]=TRUE;//v0并入S集 for(i=1;i<G.vexnum;++i)//其余G.vexnum-1个顶点 {//开始主循环,每次求得v0到某个顶点v的最短路径,并将v并入S集 min=INFINITY; for(w=0;w<G.vexnum;++w)//对所有顶点检查 if(!final[w]&&d[w]<min)//在S集之外的顶点中找离v0最近的顶点,赋值给v,距离赋值给min {v=w;min=d[w];} final[v]=TRUE;//v并入S集 for(w=0;w<G.vexnum;++w)//根据新并入的顶点更新不在S集中的顶点到v0的距离和路径数组 if(!final[w]&&min<INFINITY&&G.arcs[v][w].adj<INFINITY&&(min+G.arcs[v][w].adj<d[w])) {//w不属于S集且v0->v->w的距离<目前v0->w的距离 d[w]=min+G.arcs[v][w].adj;//更新d[w] for(j=0;j<G.vexnum;++j)//修改p[w],v0到w经过的顶点包括v0到v经过的顶点再加上顶点w p[w][j]=p[v][j]; p[w][w]=TRUE; }//if }//for }
//floyd,求任意两顶点的最短路径 Status ShortestPath_floyd(Graph p) { int path[][][]//3维矩阵记录路径 int Distance[][]//二维矩阵记录两点间距离 for(v=0;v<G.vexnum;v++)//对各点初始已知距离和路径 for(w=0;w<G.vexnum;w++) { d[v][w]=G.arc[v][w];//init the array for(u=0;u<G.vexnum;u++) p[v][w][u]=0; if(d[v][w]){//v到w之间有直接路径 p[v][w][v]=p[v][w][w]=1;//v到w经过v和w } } for(u=0;u<G.vexnum;u++) for(v=0;v<G.vexnum;v++) for(w=0;w<G.vexnum;w++) if(d[v][u]+d[u][w]<d[v][w])//从v到w的一条路径更短 { d[v][w]=d[v][u]+d[u][w]; for(i=0;i<G.vexnum;i++) p[v][w][i]=p[v][[u][i]||p[u][w][i]//v到w经过v到u和u到w的所有路径 } }