(算法设计技巧与分析)Kruskal

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;
	}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值