#include<iostream>
#include<iomanip>
using namespace std;
struct Edge //均为无向图边集
{
char startkey;
char endkey;
int weight; //权值
};
class Kruskal
{
public:
Kruskal(Edge* _edges,int _edgenum,char *_keyArray,int _vertexnum);
void SortEdge();
void MSTKruskal(); //找到最小生成树
int FindSet(int *vertex,int childnum); //找到包含下标为childnum元素的集合中的一个代表元素
void MakeSet(int *vertex,int vertexnum); //初始化各集合,初始时各元素所在集合的代表元素为自己下标
int FindKey(char key); //找到key对应在keyArray的位置,映射到vertex的下标
void Union(Edge *edge);
void OutputTree();
private:
int kruskalnum;
int edgenum;
int vertexnum;
char *keyArray;
Edge *kruskaltree;
Edge *edges;
};
Kruskal::Kruskal(Edge* _edges,int _edgenum,char *_keyArray,int _vertexnum)
{
edges = new Edge[_edgenum];
kruskaltree = new Edge[_vertexnum - 1]; //最小生成树的边数只比节点-1
keyArray = new char[_vertexnum];
int i;
for(i = 0; i < _edgenum; i++)
{
edges[i].startkey = _edges[i].startkey;
edges[i].endkey = _edges[i].endkey;
edges[i].weight = _edges[i].weight;
}
for(i = 0; i < _vertexnum;i++)
keyArray[i] = _keyArray[i];
edgenum = _edgenum;
kruskalnum = 0;
vertexnum = _vertexnum;
SortEdge();
}
void Kruskal::SortEdge() //这里排序就只做简单的插入排序
{
int i,j;
Edge temp;
for(i = 1;i < edgenum;i++)
{
temp.startkey = edges[i].startkey;
temp.endkey = edges[i].endkey;
temp.weight = edges[i].weight;
for(j = i - 1;j >= 0;j--)
{
if(edges[j].weight > temp.weight)
{
edges[j + 1].startkey = edges[j].startkey;
edges[j + 1].endkey = edges[j].endkey;
edges[j + 1].weight = edges[j].weight;
}
else
break;
}
edges[j + 1].startkey = temp.startkey;
edges[j + 1].endkey = temp.endkey;
edges[j + 1].weight = temp.weight;
}
}
void Kruskal::MSTKruskal()
{
int i;
int startnum,endnum;
int *vertex = new int[vertexnum];
MakeSet(vertex,vertexnum);
for(i = 0; i < edgenum;i++)
{
startnum = FindKey(edges[i].startkey);
endnum = FindKey(edges[i].endkey);
startnum = FindSet(vertex,startnum);
endnum =FindSet(vertex,endnum);
if(startnum != endnum)
{
vertex[endnum] = startnum;
Union(&(edges[i]));
if(kruskalnum == (vertexnum + 1)) //当最小生成树边数为节点数 - 1就可以直接退出去了
return;
}
}
}
int Kruskal::FindSet(int *vertex,int childnum)
{
while(vertex[childnum] != childnum)
{
childnum = vertex[childnum];
}
return childnum;
}
void Kruskal::MakeSet(int *vertex,int vertexnum)
{
for(int i = 0; i < vertexnum;i++)
{
vertex[i] = i;
}
}
int Kruskal::FindKey(char key)
{
for(int i = 0; i < vertexnum;i++)
{
if(keyArray[i] == key)
return i;
}
}
void Kruskal::Union(Edge *edge)
{
kruskaltree[kruskalnum].startkey = edge->startkey;
kruskaltree[kruskalnum].endkey = edge->endkey;
kruskaltree[kruskalnum].weight = edge->weight;
kruskalnum++;
}
void Kruskal::OutputTree()
{
cout<<"The result of Kruskal Spanning Tree is :"<<endl;
for(int i = 0; i < kruskalnum;i++)
cout<<setw(5)<<kruskaltree[i].startkey<<setw(5)<<kruskaltree[i].endkey<<setw(10)<<kruskaltree[i].weight<<endl;
}
int main()
{
Edge edges[] = {{'a','b',4},{'a','h',8},{'b','h',11},{'b','c',8},{'c','i',2},{'c','d',7},{'c','f',4},{'d','e',9},{'d','f',14},{'g','f',2},{'h','g',1},{'h','i',7},{'i','g',6},{'e','f',10}};
char vertex[] = {'a','b','c','d','e','f','g','h','i'};
Kruskal *kruskal = new Kruskal(edges,14,vertex,9);
kruskal->MSTKruskal();
kruskal->OutputTree();
return 0;
}