Kruskal算法实现

原创 2016年06月02日 11:53:38
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <queue>
#define NUM 6
#define MAXSIZE 30
using namespace std;

//定义并查集树
typedef struct UNode
{
     int data;
     int rank;
     int parent;
} UNode,UFSTree;

//定义邻接矩阵
typedef struct Node
{
     int num;
     int data;
} Node;
typedef struct MGraph
{
     int edges[NUM][NUM];
     int n,e;
} MGraph;

//定义边
typedef struct Edge
{
     int u;//起点
     int v;//终点
     int w;//权值

     bool operator < (const Edge &a) const
     {
	  return w > a.w;
     }
} Edge;

MGraph *build_graph();
void kruskal(MGraph *mgraph);
void MAKE_SET(UFSTree t[], int n);
int FIND_SET(UFSTree t[], int x);
void UNION(UFSTree t[], int x, int y);

int main(void )
{
     MGraph *mgraph;

     mgraph=build_graph();
     kruskal(mgraph);
     return 0;
}

MGraph *build_graph()
{
     MGraph *mgraph;
     int i,j;
     int this_edges=0;
     int arrays[NUM][NUM]={{0,6,1,5,INT_MAX,INT_MAX},
			   {6,0,5,INT_MAX,3,INT_MAX},
			   {1,5,0,5,6,4},
			   {5,INT_MAX,5,0,INT_MAX,2},
			   {INT_MAX,3,6,INT_MAX,0,6},
			   {INT_MAX,INT_MAX,4,2,6,0}};
     mgraph=(MGraph *)malloc(sizeof(MGraph));
     for(i=0;i<NUM;i++)
     {
	  for(j=0;j<NUM;j++)
	  {
	       mgraph->edges[i][j]=arrays[i][j];
	       if(arrays[i][j]!=0 && arrays[i][j]!=INT_MAX)
	       {
		    this_edges++;
	       }
	  }
     }
     mgraph->n=NUM;
     mgraph->e=this_edges;

     //测试生成的邻接矩阵
     printf("node=%d,edges=%d\n",mgraph->n,mgraph->e);
     for(i=0;i<NUM;i++)
     {
	  for(j=0;j<NUM;j++)
	  {
	       if(mgraph->edges[i][j]!=INT_MAX)
	       {
		    printf("%3d",mgraph->edges[i][j]);
	       }
	       else
	       {
		    printf("%3c",'&');
	       }
	  }
	  printf("\n");
     }
     
     return mgraph;
}

//Kruskal算法
void kruskal(MGraph *mgraph)
{
     int i,j;
     int k;			// 存储已并入的边数
     int u1,v1;			// 存储当前最小边
     int sn1,sn2;		// 存储两个顶点所属集合
     UFSTree t[MAXSIZE];	// 存储并查集树
     Edge E[MAXSIZE];		// 存储所有的边
     priority_queue<Edge> pq;	// 优先队列,每次弹出最小边

     //把所有边存入优先队列
     k=1;
     for(i=0;i<mgraph->n;i++)
     {
	  for(j=0;j<=i;j++)
	  {
	       if(mgraph->edges[i][j]!=0 && mgraph->edges[i][j]!=INT_MAX)
	       {
		    E[k].u=i;
		    E[k].v=j;
		    E[k].w=mgraph->edges[i][j];
		    pq.push(E[k]);
	       }
	  }
     }

     MAKE_SET(t,mgraph->n);	// 初始化并查集

     //每次选出最小边并入
     k=1;
     while(k<mgraph->n)
     {
	  u1=pq.top().u;
	  v1=pq.top().v;

	  sn1=FIND_SET(t,u1);
	  sn2=FIND_SET(t,v1);
	  if(sn1!=sn2)
	  {
	       printf("%d-%d: %d\n",u1,v1,pq.top().w);
	       k++;
	       UNION(t,u1,v1);
	  }
	  pq.pop();
     }
     
}

//初始化并查集
void MAKE_SET(UFSTree t[], int n)
{
     int i;
     for(i=0;i<n;i++)
     {
	  t[i].data=i;
	  t[i].rank=0;
	  t[i].parent=i;
     }
}
//并查集查找
int FIND_SET(UFSTree t[], int x)
{
     if(x!=t[x].parent)
	  return FIND_SET(t,t[x].parent);
     else
	  return x;
}
//并查集合并
void UNION(UFSTree t[], int x, int y)
{
     x=FIND_SET(t,x);
     y=FIND_SET(t,y);

     if(t[x].rank > t[y].rank)
	  t[y].parent=x;
     else
     {
	  t[x].parent=y;
	  if(t[x].parent==t[y].parent)
	       t[y].rank++;
     }
}

HashMap的实现机制、实现自己的HashMap

在数据结构中,数组列表插入删除不方便,链表查找效率不高。而HashMap拥有了这两者的优点。HashMap本质上是由数组+链表组成的结构。源码分析注意:此部分参考自[https://dzone.com...
  • joson793847469
  • joson793847469
  • 2016年10月04日 09:22
  • 885

关于set想说的(一)之Set的实现类及必要的方法

最近看到了《Thinking in Java》的第17章 容器深入探究,17.6 Set和存储顺序。自己写了写测试代码,加深下理解。主要设计toString()方法(主要是为了方便打印),equals...
  • fan2012huan
  • fan2012huan
  • 2016年03月23日 10:46
  • 1731

Map集合及其实现类

Map 接口 ----|HashMap -------------extends Map ----|Hashtable -------------imp...
  • zhou920786312
  • zhou920786312
  • 2017年04月04日 14:49
  • 402

三子棋的实现的实现的实现

三子棋的实现三子棋是一个简单的游戏,特别适合编程新手练习,这里我们就简单介绍一下c语言实现三子棋的过程。—————————————————我是下划线——————————————首先我们将函数分为两大部...
  • Cyrus_wen
  • Cyrus_wen
  • 2017年12月02日 19:09
  • 48

printf内部实现

通过printf的简易实现,熟悉变长参数表
  • dudubird90
  • dudubird90
  • 2015年09月16日 15:26
  • 2346

C++笔试题 String类的实现

这个在面试或笔试的时候常问到或考到。 已知类String的原型为: class String { public:      String(const char *str = NULL);// 普通...
  • caoshangpa
  • caoshangpa
  • 2016年05月29日 09:12
  • 3888

乐观锁的两种实现方式

什么场景下需要使用锁? 在多节点部署或者多线程执行时,同一个时间可能有多个线程更新相同数据,产生冲突,这就是并发问题。这样的情况下会出现以下问题: 更新丢失:一个事务更新数据后,被另一个更新数据的...
  • lxy344x
  • lxy344x
  • 2017年08月01日 23:25
  • 1335

java,什么是序列化,怎么实现序列化

转自:http://zhidao.baidu.com/question/202556575.html?qbl=relate_question_0&word=%CA%B2%C3%B4%CA%C7java...
  • zhangzhangjava
  • zhangzhangjava
  • 2016年04月12日 17:33
  • 3243

【STL】 vector 模拟实现

上一篇博客说了一下list的使用,其实vector用法基本上和list是一样的,所以此篇博客就只模拟实现以下vector。vector你可以把它理解成一个顺序表或者数组。只是STL里的vector是由...
  • pointer_y
  • pointer_y
  • 2016年09月23日 19:55
  • 662

malloc实现原理

本文大致讲解一下Linux下malloc的底层实现原理。 首先malloc肯定是从堆中分配内存,而堆又在用户空间中占据什么位置?通过下面这张图可以看出来: 很明显是32位系统,寻址空间是4...
  • xieyihua1994
  • xieyihua1994
  • 2016年10月03日 10:52
  • 507
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Kruskal算法实现
举报原因:
原因补充:

(最多只允许输入30个字)