伪代码
邻接表储存MST
/*图的邻接表结构定义*/
typedef struct ENode{
int v1, v2;
int Weight;
} * Edge;
struct AdjVNode{
int AdjV;
int Weight;
AdjVNode *Next;
};
typedef struct VNode{
AdjVNode *EdgeFirst;
string Data;
} AdjList[MaxV];
typedef struct LGNode{
int Nv, Ne;
AdjList L;
int Data;
} * LGraph;
LGraph CreateGraph(int Nv)
{
LGraph G = new LGNode();
G->Nv = Nv;
return G;
}
void InsertEdge(LGraph G, Edge E)
{
AdjVNode *A = new AdjVNode;
A->AdjV = E->v2; A->Weight = E->Weight;
A->Next = G->L[E->v1].EdgeFirst;
G->L[E->v1].EdgeFirst = A;
A = new AdjVNode;
A->AdjV = E->v1; A->Weight = E->Weight;
A->Next = G->L[E->v2].EdgeFirst;
G->L[E->v2].EdgeFirst = A;
}
void PrintMST(LGraph MST)
{
AdjVNode *A;
for (int i = 0; i < MST->Nv; i++)
{
A = MST->L[i].EdgeFirst;
cout << i << "->";
while (A)
{
cout << A->AdjV << "->";
A = A->Next;
}
cout << "NULL" << endl;
}
}
void DeleteGraph(LGraph MST)
{
AdjVNode *A;
for (int i = 0; i < MST->Nv; i++)
{
while (MST->L[i].EdgeFirst)
{
A = MST->L[i].EdgeFirst;
MST->L[i].EdgeFirst = A->Next;
delete A;
}
}
delete MST;
}
最小堆及其操作
/*最小优先队列*/
typedef struct MinHeapNode{
Edge *Data; //最小堆存的数据是边
int Size;
int Capacity;
} * MinHeap;
MinHeap CreateMinHeap(int MaxSize)
{
MinHeap H = new MinHeapNode;
H->Size = 0;
H->Capacity = MaxSize;
H->Data = new Edge[MaxSize + 1];
H->Data[0] = new ENode;
H->Data[0]->Weight = -1;
return H;
}
void InsertMinHeap(MinHeap H, Edge E)
{
if(H->Size == H->Capacity)
return;
Edge AddE = new ENode;
AddE->Weight = E->Weight;
AddE->v1 = E->v1;
AddE->v2 = E->v2;
int x = AddE->Weight;
int child;
for (child = ++H->Size; x < H->Data[child / 2]->Weight; child /= 2)
H->Data[child] = H->Data[child / 2];
H->Data[child] = AddE;
}
Edge DeleteMinHeap(MinHeap H)
{
if(H->Size == 0)
return H->Data[0];
Edge DelE = H->Data[1];
int x = H->Data[H->Size--]->Weight;
int parent, child;
for ( parent = 1; parent * 2 <= H->Size; parent = child )
{
child = 2 * parent;
if(H->Data[child + 1]->Weight < H->Data[child]->Weight && child != H->Size)
child++;
if(x > H->Data[child]->Weight)
H->Data[parent] = H->Data[child];
else
break;
}
H->Data[parent] = H->Data[H->Size + 1];
return DelE;
}
void DeleteHeap(MinHeap H)
{
for (int i = 0; i <= H->Size; i++)
delete H->Data[i];
delete[] H->Data;
delete H;
}
Find + Union
int FindSet(int Set[], int v)
{
if(Set[v] < 0)
return v;
else
return FindSet(Set, Set[v]);
}
void UnionSet(int Set[], int R1, int R2) //合并集合
{
if(Set[R1] < Set[R2]) //R1集合更多
{
Set[R1] += Set[R2];
Set[R2] = R1;
}
else
{
Set[R2] += Set[R1];
Set[R1] = R2;
}
}
Kruskal算法
LGraph Kruskal()
{
int Nv, Ne;
cin >> Nv >> Ne;
LGraph MST = CreateGraph(Nv);
MinHeap H = CreateMinHeap(Ne);
Edge E = new ENode;
for (int i = 0; i < Ne; i++)
{
cin >> E->v1 >> E->v2 >> E->Weight;
InsertMinHeap(H, E);
}
delete E;
int *Set = new int[Nv];
memset(Set, -1, Nv * sizeof(int));
Edge MinE;
while (MST->Ne < MST->Nv - 1) //相等时,刚好所有顶点都加入生成树
{
MinE = DeleteMinHeap(H);
int R1 = FindSet(Set, MinE->v1);
int R2 = FindSet(Set, MinE->v2);
if(R1 != R2)
{
UnionSet(Set, R1, R2);
InsertEdge(MST, MinE);
MST->Ne++;
MST->Data += MinE->Weight;
delete MinE;
}
}
delete[] Set;
DeleteHeap(H);
return MST;
}
int main()
{
LGraph MST = Kruskal();
PrintMST(MST);
cout << MST->Data << endl;
DeleteGraph(MST);
system("pause");
return 0;
}
程序运行
input:
10 17
0 2 5
0 1 8
1 4 5
1 2 5
1 5 4
4 5 4
2 3 8
2 6 4
5 6 4
5 8 2
3 6 7
6 8 3
3 7 5
6 7 5
6 9 6
8 9 7
7 9 6
output:
0->2->NULL
1->5->NULL
2->0->6->NULL
3->7->NULL
4->5->NULL
5->4->1->8->NULL
6->7->2->8->NULL
7->9->6->3->NULL
8->6->5->NULL
9->7->NULL
38
请按任意键继续. . .
完整代码
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int MaxV = 100;
/*图的邻接表结构定义*/
typedef struct ENode{
int v1, v2;
int Weight;
} * Edge;
struct AdjVNode{
int AdjV;
int Weight;
AdjVNode *Next;
};
typedef struct VNode{
AdjVNode *EdgeFirst;
string Data;
} AdjList[MaxV];
typedef struct LGNode{
int Nv, Ne;
AdjList L;
int Data;
} * LGraph;
LGraph CreateGraph(int Nv)
{
LGraph G = new LGNode();
G->Nv = Nv;
return G;
}
void InsertEdge(LGraph G, Edge E)
{
AdjVNode *A = new AdjVNode;
A->AdjV = E->v2; A->Weight = E->Weight;
A->Next = G->L[E->v1].EdgeFirst;
G->L[E->v1].EdgeFirst = A;
A = new AdjVNode;
A->AdjV = E->v1; A->Weight = E->Weight;
A->Next = G->L[E->v2].EdgeFirst;
G->L[E->v2].EdgeFirst = A;
}
void PrintMST(LGraph MST)
{
AdjVNode *A;
for (int i = 0; i < MST->Nv; i++)
{
A = MST->L[i].EdgeFirst;
cout << i << "->";
while (A)
{
cout << A->AdjV << "->";
A = A->Next;
}
cout << "NULL" << endl;
}
}
void DeleteGraph(LGraph MST)
{
AdjVNode *A;
for (int i = 0; i < MST->Nv; i++)
{
while (MST->L[i].EdgeFirst)
{
A = MST->L[i].EdgeFirst;
MST->L[i].EdgeFirst = A->Next;
delete A;
}
}
delete MST;
}
/*最小优先队列*/
typedef struct MinHeapNode{
Edge *Data; //最小堆存的数据是边
int Size;
int Capacity;
} * MinHeap;
MinHeap CreateMinHeap(int MaxSize)
{
MinHeap H = new MinHeapNode;
H->Size = 0;
H->Capacity = MaxSize;
H->Data = new Edge[MaxSize + 1];
H->Data[0] = new ENode;
H->Data[0]->Weight = -1;
return H;
}
void InsertMinHeap(MinHeap H, Edge E)
{
if(H->Size == H->Capacity)
return;
Edge AddE = new ENode;
AddE->Weight = E->Weight;
AddE->v1 = E->v1;
AddE->v2 = E->v2;
int x = AddE->Weight;
int child;
for (child = ++H->Size; x < H->Data[child / 2]->Weight; child /= 2)
H->Data[child] = H->Data[child / 2];
H->Data[child] = AddE;
}
Edge DeleteMinHeap(MinHeap H)
{
if(H->Size == 0)
return H->Data[0];
Edge DelE = H->Data[1];
int x = H->Data[H->Size--]->Weight;
int parent, child;
for ( parent = 1; parent * 2 <= H->Size; parent = child )
{
child = 2 * parent;
if(H->Data[child + 1]->Weight < H->Data[child]->Weight && child != H->Size)
child++;
if(x > H->Data[child]->Weight)
H->Data[parent] = H->Data[child];
else
break;
}
H->Data[parent] = H->Data[H->Size + 1];
return DelE;
}
void DeleteHeap(MinHeap H)
{
for (int i = 0; i <= H->Size; i++)
delete H->Data[i];
delete[] H->Data;
delete H;
}
int FindSet(int Set[], int v)
{
if(Set[v] < 0)
return v;
else
return FindSet(Set, Set[v]);
}
void UnionSet(int Set[], int R1, int R2) //合并集合
{
if(Set[R1] < Set[R2]) //R1集合更多
{
Set[R1] += Set[R2];
Set[R2] = R1;
}
else
{
Set[R2] += Set[R1];
Set[R1] = R2;
}
}
LGraph Kruskal()
{
int Nv, Ne;
cin >> Nv >> Ne;
LGraph MST = CreateGraph(Nv);
MinHeap H = CreateMinHeap(Ne);
Edge E = new ENode;
for (int i = 0; i < Ne; i++)
{
cin >> E->v1 >> E->v2 >> E->Weight;
InsertMinHeap(H, E);
}
delete E;
int *Set = new int[Nv];
memset(Set, -1, Nv * sizeof(int));
Edge MinE;
while (MST->Ne < MST->Nv - 1) //相等时,刚好所有顶点都加入生成树
{
MinE = DeleteMinHeap(H);
int R1 = FindSet(Set, MinE->v1);
int R2 = FindSet(Set, MinE->v2);
if(R1 != R2)
{
UnionSet(Set, R1, R2);
InsertEdge(MST, MinE);
MST->Ne++;
MST->Data += MinE->Weight;
delete MinE;
}
}
delete[] Set;
DeleteHeap(H);
return MST;
}
int main()
{
LGraph MST = Kruskal();
PrintMST(MST);
cout << MST->Data << endl;
DeleteGraph(MST);
system("pause");
return 0;
}