kruskal 算法b

使用堆排序,并查集实现kruskal算法。

堆排序算法见:http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html

并查集合:http://www.cnblogs.com/cherish_yimi/archive/2009/10/11/1580839.html

#include "iostream"
#include "vector"
#include "fstream"
using namespace std;
struct edge
{
	int u;
	int v;
	int weight;
};
std::vector<edge> E;//边的数组
std::vector<int> rank;//秩,树的最大高度
std::vector<int> father;//父亲节点
int vertexnum;//节点数
int edgenum;//边数
void make_set(int x);// 初始化集合
void swap(edge *a,edge *b);//交换边
void initialvector(){// 初始化
	E.resize(edgenum);
	rank.resize(vertexnum,0);
	father.resize(vertexnum);
	for(int i = 0;i < vertexnum;i++){
		make_set(i);
	}
}
void getData(){//获取数据
	ifstream in("data");
	in>>vertexnum>>edgenum;
	initialvector();
	int from,to;
	double w;
	int i = 0;
	while(in>>from>>to>>w){
		E[i].u = from;
		E[i].v = to;
		E[i].weight = w;
		i++;
	}
}
void HeapAdjust(int i,int size){
	int lchild = 2*i + 1;//i的左孩子节点序号 
	int rchild = 2*i + 2;//i的右孩子节点序号 
	int min = i;
	if(i < size/2){//如果i是叶节点就不用进行调整
		if(lchild < size && E[lchild].weight < E[min].weight){
			min = lchild;
		}
		if(rchild < size && E[rchild].weight < E[min].weight){
			min = rchild;
		}
		if(min != i){
			swap(&E[i],&E[min]);
			HeapAdjust(min,size);//重新调整被破坏的堆
		}
	}
}
void swap(edge *a,edge *b){
	edge temp;
	temp = *a;
	*a = *b;
	*b = temp;
}
void make_heap(){
	for(int i = edgenum/2 -1;i>=0;i--){
		HeapAdjust(i,edgenum);
	}
}
edge minedge(int &m){
	swap(E[0],E[m]);
	HeapAdjust(0,--m);
	return E[m+1];
}
void make_set(int x){
	father[x] = x;
}
int find_set(int x){// 查找x元素所在的集合,回溯时压缩路径
	if(x != father[x]){
		father[x] = find_set(father[x]);
	}
	return father[x];
}
/* 
   按秩合并x,y所在的集合
   下面的那个if else结构不是绝对的,具体根据情况变化
   但是,宗旨是不变的即,按秩合并,实时更新秩。
*/
void unionset(int x,int y){
	x = find_set(x);
	y = find_set(y);
	if(x == y) return;
	if(rank[x] > rank[y]){
		father[y] = x ;
	}else{
		if(rank[x] == rank[y]){
			rank[y]++;
		}
		father[x] = y;
	}
}
int main(int argc, char const *argv[])
{
	getData();  
	int u,v,i = 0;
	int m = edgenum - 1;
	std::vector<edge> minset;
	edge min_edge;
	make_heap();
	while(i < edgenum-1  && m > 0){
		min_edge = minedge(m);
		u = find_set(min_edge.u);
		v = find_set(min_edge.v);
		if(u != v){
			unionset(u,v);
			minset.push_back(min_edge);
			cout<<min_edge.u<<"->"<<min_edge.v<<"\t"<<min_edge.weight<<endl;
			i++;
		}
	}

}

data:

7 11
0 1 7
0 3 5
1 2 8
1 3 9
1 4 7
2 4 5
3 4 15
3 5 6
4 5 8
4 6 9
5 6 11

参考:http://www.cnblogs.com/cherish_yimi/archive/2009/10/11/1580839.html

http://www.slyar.com/blog/kruskal-disjoint-sets-c.html

http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html

你可能感兴趣的:(kruskal 算法b)