赞
踩
伪码描述:
void Kruskal( Graph G ) {
MST = { } ; //MST用邻接表
while( MST 中不到|V| -1 条边&& E 中还有边) {
从E 中取一条权重最小的边E(v,w) ;
将E(v,w)从E 中删除;
if( E(V,W)不在MST 中构成回路) 将E(V,W)加入MST;
else 彻底无视E(V,W); }
if( MST 中不到|V| 1 条边) Error ( “生成树不存在”);
}
Part 1——并查集
void InitializeVSet(int N,SetType VSet) { for(int i=0;i<N;i++) VSet[i]=-1; ///N个集合,下标从0开始 } int Find(Vertex X,SetType VSet)//找顶点集合 { if(VSet[X]<0) return X;// else return VSet[X]=Find(VSet[X],VSet);//压缩路径 } void Union(SetType VSet,int root1,int root2) { if(VSet[root1]<VSet[root2]){//小的并入大的 VSet[root1]+=VSet[root2]; VSet[root2]=root1; } else{ VSet[root2]+=VSet[root1]; VSet[root1]=root2; } } int check(SetType VSet,Vertex v1,Vertex v2) { int root1,root2; root1=Find(v1,VSet);root2=Find(v2,VSet); if(root1==root2) return -1; else{ Union(VSet,root1,root2); return 1; } }
Part 2——最小堆
void percDown(Edge ESet,int p,int N)//找顶点p的正确位置 { int parent,child; struct ENode X;X=ESet[p]; for(parent=p;(parent*2+1)<N;parent=child){///堆从0开始 ,注意堆中parent和child的标号关系 child=parent*2+1; if(child!=N-1&&ESet[child+1].weight<ESet[child].weight) child=child+1; if(ESet[child].weight<X.weight) ESet[parent]=ESet[child];/ else break; } ESet[parent]=X; } void InitializeESet(LGraph Graph,Edge ESet)//将图中边输入到ESet中 无向边 { int ECount=0; int i; for(i=0;i<Graph->Nv;i++){ for(PtrA w=Graph->G[i].FirstEdge;w;w=w->next) if(i<w->AdjV){ ESet[ECount].v1=i;ESet[ECount].v2=w->AdjV; ESet[ECount++].weight=w->weight;} } for(ECount=(Graph->Ne-2)/2;ECount>=0;ECount--) percDown(ESet,ECount,Graph->Ne); } int GetMin(Edge ESet,int currentsize) { struct ENode tmp; tmp=ESet[0]; ESet[0]=ESet[currentsize-1]; ESet[currentsize-1]=tmp; percDown(ESet,0,currentsize-1); return currentsize-1; }
Part 3——Kruskal
int Kurskal(LGraph Graph,LGraph MST)//返回最终权重 { weightType Totalweight; int ECount;//MST中收录边数 int currentsize;//边集数 MST=createG(Graph->Nv); Edge ESet; ESet=(Edge)malloc(sizeof(struct ENode)*Graph->Ne);//! ~~我是初始化分界线~~ InitializeESet(Graph,ESet);//初始化边集 SetType VSet; InitializeVSet(Graph->Nv,VSet);//初始化顶点并查集 ECount=0; Totalweight=0; currentsize=Graph->Ne; while(ECount<Graph->Nv-1){ currentsize=GetMin(ESet,currentsize);//最小权重边位置 if(currentsize<0) break; if(check(VSet,ESet[currentsize].v1,ESet[currentsize].v2)==1) { Insert(MST,ESet+currentsize); Totalweight+=ESet[currentsize].weight; ECount++; } } if(ECount!=Graph->Nv-1) return -1; else return Totalweight; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。