最小生成树(Kruskal算法)

算法简介:

Kruskal算法是一种用来查找最小生成树的算法,由Joseph Kruskal在1956年发表。用来解决同样问题的还有Prim算法和Boruvka算法等。三种算法都是贪心算法的应用。和Boruvka算法不同的地方是,Kruskal算法在图中存在相同权值的边时也有效。

算法讲解:

将所有的边按照从小到大进行排序。然后依此从最小边开始检测,如果当前边的两个节点拥有相同的根节点,则构成回路。如果没有相同的根节点则证明不会造成回路,将当前两个节点合并成一棵树。(确定是否造成回路会用到并查集的概念,并查集的作用就是获得当前节点的根节点。)直至所有的边全部检测完毕就完成了我们的寻找最小生成树的任务,这就是克鲁斯卡尔算法。

代码实现:

//首先定义边的类
class Road{
	int a, b;      //连接一条边的两个节点
	int w;         //该条边的权值
}
//边的列表,假设列表中已经存有数据
List<Road> roadList = new ArrayList<Road>();
int v[maxsize];         //并查集数组
//查找根节点的方法
int getRoot(int a){
	while(a != v[a]) a = v[a];
	return a;
}

void Kruskal(Graph g, List<Road> roadList){
	int N, G, a, b;
	N = g.n;
	E = g.edge;
	for(int i=0; i<N, i++){
		//令节点的根节点等于其本身
		v[i] = i;
	}
	//对list的排序方法省略
	Sort(roadList);
	for(int i=0; i<E; i++){
		a = getRoot(roadList.get(i).a);
		b = getRoot(roadList.get(i).b);
		if(a != b){
			v[a] = b;
		}
	}
}

时间复杂度:

该算法的时间主要花费在边的排序和单层循环上,排序算法是线性级的,因此任务主要的时间都花费在边权值的排序上。 该算法的时间复杂度由排序算法而定,排序所要处理的数据量由于边的数量有关。因此,影响该算法效率的因素是边的数量。该算法适用于边数较少的稀疏图。

posted @ 2018-07-17 11:15  AllenTung  阅读(381)  评论(0)    收藏  举报