摘要:本文用Kruskal算法求解最小生成树,算法本身是很简单的,但是用到了比较多的数据结构.该算法由堆操控,时间界是O(|E|log|E|)
(1)基本思路:
[1]每次都选择所有没有被选择过的边中最小的一条边,如果这条边不与已经选择的边构成一个圈,那么这条边就被选中,否则,删除.
[2]当被选中的边数量达到|V|-1终止算法.
(2)所用的数据结构:
[1]堆:用来存放边,每次找到最小的边
[2]相交/不想交集合,用来判断选择的边是否构成一个圈.
[3]如何判断?当两个节点在同一个集合中,那么意味着除了这条边,还有其他的路径连接这两条边,必然构成一个圈.
[4]边的数据结构(自己定义的),堆的基本数据元素就是这些边构成的,所以所有堆的操作都要修改(这个工作繁琐但是不难)
struct Edgestructure
{
int length;
int vertex1;
int vertex2;
};
(3)核心算法代码
void ReadGraphIntoHeap(Graph G,Heap H)
{
int i = 1;
for(int j = 1;j <= Number;j++)
{
while(G[j]->Next!=NULL)
{
H->Element[i] = (Edge)malloc(sizeof(Edgestructure));
H->Element[i]->length = G[j]->Next->weight;
H->Element[i]->vertex1 = j;
H->Element[i++]->vertex2 = G[j]->Next->Element;
G[j] = G[j]->Next;
}
}
H->heapsize = i-1;
}
void Createminimumtree(Graph G,Graph MinimumTree)
{
int EdgeAccepted;
int U,V;
int i = 0;
int Uset,Vset;
Heap H = CreateHeap(Number);
Edge E;
Disjset S;
InitializeDis(S);
ReadGraphIntoHeap(G,H);
BuildHeap(H);
EdgeAccepted = 1;
while(EdgeAccepted < Number-1)
{
E = DeleteMin(H);
U = E->vertex1;
V = E->vertex2;
Uset = Find(S,U);
Vset = Find(S,V);
if(Uset!=Vset)
{
Union_height(S,Uset,Vset);
Insert(MinimumTree[U],V,E->length);
EdgeAccepted++;
}
}
}