最小生成树,最短路径的基本算法

最小生成树:

//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的所有路径
						}
}



你可能感兴趣的:(最小生成树,最短路径的基本算法)