最小生成树之Kruskal算法的实现

 克鲁斯卡尔算法定义:(百度贴来的)

  假设 WN=(V,{E}) 是一个含有 n 个顶点的连通网,则按照克鲁斯卡尔算法构造最小生成树的过程为:先构造一个只含 n 个顶点,而边集为空的子图,若将该子图中各个顶点看成是各棵树上的根结点,则它是一个含有 n 棵树的一个森林。之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,也就是说,将这两个顶点分别所在的两棵树合成一棵树;反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。依次类推,直至森林中只有一棵树,也即子图中含有 n-1条边为止

说一些自己的看法:

首先需要把所有的边信息整合到最小堆中,然后每一次取出当前堆中边权值最小的(这里需要对自定义类重载这些比较),拿出边的两个顶点,如果在一个子集中就丢掉,反之放到生成树中。最小生成树是不可能有回路的,所以根据这个描述可以知道权值最小的两条边是一定要进入生成树中。

为了搭建这个算法,需要图结构,最小生成树结构(为了方便使用这个树,做了个封装),最小堆,并查集。

并查集链接:点击打开链接   http://blog.csdn.net/zlhy_/article/details/8249825


#pragma once
#include<iostream>
#include<fstream>
#include"MinSpanTree.h"
#include"F:\QQPCmgr\documents\visual studio 2010\Projects\Graph\Graph_list\GraphAdjList.h"
#include"F:\QQPCmgr\documents\visual studio 2010\Projects\UFSet\UFSet\UFset.h"
#include"F:\QQPCmgr\Documents\Visual Studio 2010\Projects\Heap\Heap\MinHeap.h"
using namespace std;

template<class T, class E> 
void KruskalAlgorithm(GraphAdjList<T,E> &targetG, MinSpanTree<E> &targetMSTree)
{
	MSTEdgeNode<E> tempEdgeNode;
	int verticesNum = targetG.GetVerticesNum();
	int edgesNum = targetG.GetEdgesNum();

	int *arr = new int[verticesNum];
	for(int i = 0; i < verticesNum; i++)
	{
		arr[i] = i;
	}
	UFSet<int> us(arr, verticesNum, -1);

	MSTEdgeNode<E> *arrEdgeNode = new MSTEdgeNode<E>[edgesNum];
	targetG.GetAllEdgesInformation(arrEdgeNode); //这是图提供的一个对外接口,把边的所有信息整合到一个数组中,这个数组类型也是模板的

	MinHeap<MSTEdgeNode<E>> mh(arrEdgeNode, edgesNum);

	int edgeCount = 1;
	while(edgeCount < verticesNum) //要是连通图才可以(有最小生成树)
	{
		mh.RemoveMinelem(tempEdgeNode);

		if(us.UnionSubSetCommon(tempEdgeNode.head, tempEdgeNode.tail) == true)//并查集的另类合并算法
		{
			targetMSTree.InsertEdge(tempEdgeNode);
			edgeCount++;
		}
	}

}


你可能感兴趣的:(数据结构,C++,C++,算法)