1. 示例:
根据如下的有权无向图寻找最小生成树。
2. 基本思想
1 将图中的边由小到大排序,得到图边的队列;
2 设置各个结点自成一个生成树;
3 如下迭代计算,直至生成树边的数量为n-1:
3.1 访问图边;
3.2 如果图边两结点不属于同一生成树,则合并为同一生成树;
3.3 将该图边存入生成树边的队列中;
4 返回生成树边队列.
3. js实现
console.log(Kruskal());
// 最小生成树:Kruskal算法
function Kruskal(){
v_num = 7;
G = [[-1,2,4,1,-1,-1,-1],[2,-1,-1,3,10,-1,-1],[4,-1,-1,2,-1,5,-1],[1,3,2,-1,7,8,4],[-1,10,-1,7,-1,-1,6],[-1,-1,5,8,-1,-1,1],[-1,-1,-1,4,6,1,-1]];
Edge_Graph=new Array();
Edge_dist=new Array();
// 找出图中所有的边及其权值
for(i=0;i<v_num;i++){
for(j=i+1;j<v_num;j++){
if(G[i][j]>0){
Edge_dist.push(G[i][j]);
Edge_Graph.push([i,j]);
}
}
}
// 按照权值由小到大的顺序排序
for(i=0;i<Edge_dist.length;i++){
for(j=i+1;j<Edge_dist.length;j++){
if(Edge_dist[i]>Edge_dist[j]){
temp=Edge_dist[i];
Edge_dist[i]=Edge_dist[j];
Edge_dist[j]=temp;
temp=Edge_Graph[i];
Edge_Graph[i]=Edge_Graph[j];
Edge_Graph[j]=temp;
}
}
}
Tree=new Array(v_num);
for(i=0;i<v_num;i++){
Tree[i]=i; // 初始时,各节点自成一类
}
Edges=new Array();
index=0;
while(Edges.length<v_num-1){ // 如果生成树的边的数量小于n-1
if(Edge_dist.length>0){ // 如果图边的数量大于0
dist=Edge_dist[0]; // 取出第一条边的权值
Edge_dist.shift(); /* 删除队列中第一条边的权值 */
edge=Edge_Graph[0]; /* 取出图中第一条边 */
Edge_Graph.shift(); /* 删除队列中第一条边 */
if(Tree[edge[0]]!=Tree[edge[1]]){ /* 如果边的两端点非同一类 */
if(Tree[edge[0]]<Tree[edge[1]]){ /* 合并为同一类 */
num_1=Tree[edge[0]];
num_2=Tree[edge[1]];
}else{
num_1=Tree[edge[1]];
num_2=Tree[edge[0]];
}
for(i=0;i<v_num;i++){
if(Tree[i]==num_2){
Tree[i]=num_1;
}
}
Edges.push(edge); /* 记录该生成树边 */
}
}else{
break;
}
}
return Edges;
}