Kruskal.cpp
#include"Union_Find.h"
#include"GraphList.h"
#include"Kruskal.h"
#include<iostream>
using namespace std;
int main()
{
GraphList gl;
gl.Initialize();
Kruskal(gl);
return 0;
}
GraphList.h
struct Edge
{
Edge(){dest=-1;weight=-1;link=0;}
Edge(int d,int w,Edge*l){dest=d;weight=w;link=l;}
int dest;//另一顶点的位置
int weight;//权重
Edge*link;//下个链
};
struct Point
{
Point(){next=0;}
Point(int d,Edge*n){data=d;next=n;}
int data;//顶点位置
Edge*next;
};
struct GraphList
{
void Initialize();//初始化
Point*root;//邻接表
int PointCount;//顶点数目
};
void GraphList::Initialize()
{
Edge*r;
PointCount=6;
root=new Point[PointCount];
for(int i=0;i<PointCount;i++)
root[i].data=i+1;
//算法初始化page152
r=new Edge(1,1,0);r->link=root[0].next;root[0].next=r;
r=new Edge(2,2,0);r->link=root[0].next;root[0].next=r;
r=new Edge(0,1,0);r->link=root[1].next;root[1].next=r;
r=new Edge(2,6,0);r->link=root[1].next;root[1].next=r;
r=new Edge(3,11,0);r->link=root[1].next;root[1].next=r;
r=new Edge(0,2,0);r->link=root[2].next;root[2].next=r;
r=new Edge(1,6,0);r->link=root[2].next;root[2].next=r;
r=new Edge(3,9,0);r->link=root[2].next;root[2].next=r;
r=new Edge(4,13,0);r->link=root[2].next;root[2].next=r;
r=new Edge(1,11,0);r->link=root[3].next;root[3].next=r;
r=new Edge(2,9,0);r->link=root[3].next;root[3].next=r;
r=new Edge(4,7,0);r->link=root[3].next;root[3].next=r;
r=new Edge(5,3,0);r->link=root[3].next;root[3].next=r;
r=new Edge(2,13,0);r->link=root[4].next;root[4].next=r;
r=new Edge(3,7,0);r->link=root[4].next;root[4].next=r;
r=new Edge(5,4,0);r->link=root[4].next;root[4].next=r;
r=new Edge(3,3,0);r->link=root[5].next;root[5].next=r;
r=new Edge(4,4,0);r->link=root[5].next;root[5].next=r;
}
Kruskal.h
#include<iostream>
using namespace std;
struct edge
{//包括起点,终点,权重的边
int start;
int end;
int weight;
edge *link;
edge(){start=0;end=0;weight=0;link=0;}
edge(int s,int e,int w,edge *l)
{start=s;end=e;weight=w;link=l;}
};
void Exchange(edge *x,edge *y)
{//交换两条边
int temp;
temp=x->start;x->start=y->start;y->start=temp;
temp=x->end;x->end=y->end;y->end=temp;
temp=x->weight;x->weight=y->weight;y->weight=temp;
}
void Copy(edge &x,edge *p)
{//复制一条边
x.start=p->start;
x.end=p->end;
x.weight=p->weight;
}
void Kruskal(GraphList gl)
{
edge *head=0,*p,*s;
Edge *node;//图的边,包括下一顶点位置和权重
Gather *ga=new Gather[gl.PointCount];//不相交集
int i,j,k;
for(i=0;i<gl.PointCount;i++)//将图中所有边集成一条链表,权重递增
{//因为是无向图,所有集合规定边的起点在邻接表的位置比终点在邻接表中的位置要小
node=gl.root[i].next;
while(node)//同一起点
{
if(i<node->dest)//判断起点和终点在邻接表中的位置
{
p=new edge(gl.root[i].data,gl.root[node->dest].data,node->weight,0);
if(head==0)//链表生成
head=p;
else
{
s=head;
while(s->link&&s->weight<p->weight)
s=s->link;
p->link=s->link;s->link=p;
if(s->weight>p->weight)
Exchange(s,p);
}
}
node=node->link;//下一结点
}
}
for(i=0;i<gl.PointCount;i++)//初始化不相交集
{ga[i].data=gl.root[i].data;ga[i].parent=0;}
p=new edge[gl.PointCount-1];//最小生成树边集
for(i=0;i<gl.PointCount-1;)
{
s=head;head=head->link;
j=0;
while(ga[j].data!=s->start)j++;//边起点所在的位置
k=j;
while(ga[k].data!=s->end)k++;//边终点所在的位置
if(Find(ga[k])->data!=Find(ga[j])->data)//判断起点和终点是否是不相交集
{Copy(p[i],s);Union(ga[k],ga[j]);i++;}
}
for(i=0;i<gl.PointCount-1;i++)
cout<<p[i].start<<" "<<p[i].end<<" "<<p[i].weight<<endl;
}
Union_Find.h
struct Gather//不相交集的数据结构
{
int data;
Gather *parent;
void MakeSet(Gather &ga,Gather &gb)
{gb.parent=&ga;}
};
Gather *Find(Gather &x)
{
Gather *root=&x,*y=&x,*temp;
while(root->parent)
root=root->parent;
while(y->parent)//压缩路径
{
temp=y->parent;
y->parent=root;
y=temp;
}
return root;
}
void Union(Gather &x,Gather &y)
{
Gather *u,*v;
u=Find(x);v=Find(y);
v->parent=u;
}