请用js实现kruskal算法
Kruskal算法是一种用于解决最小生成树问题的贪心算法。以下是一个简单的Kruskal算法的JavaScript实现:
class UnionFind {
constructor(size) {
this.parent = new Array(size);
this.rank = new Array(size).fill(0);
for (let i = 0; i < size; i++) {
this.parent[i] = i;
}
}
find(x) {
if (x !== this.parent[x]) {
this.parent[x] = this.find(this.parent[x]);
}
return this.parent[x];
}
union(x, y) {
let rootX = this.find(x);
let rootY = this.find(y);
if (rootX !== rootY) {
if (this.rank[rootX] < this.rank[rootY]) {
this.parent[rootX] = rootY;
} else if (this.rank[rootX] > this.rank[rootY]) {
this.parent[rootY] = rootX;
} else {
this.parent[rootY] = rootX;
this.rank[rootX]++;
}
}
}
}
function kruskal(n, edges) {
edges.sort((a, b) => a.weight - b.weight);
let uf = new UnionFind(n);
let res = 0;
let count = 0;
for (let edge of edges) {
let [u, v, weight] = [edge.u, edge.v, edge.weight];
if (uf.find(u) !== uf.find(v)) {
uf.union(u, v);
res += weight;
count++;
if (count === n - 1) {
break;
}
}
}
if (count !== n - 1) {
return null; // 图不连通,无法生成最小生成树
}
return res;
}
// 测试用例
let n = 4; // 顶点数量
let edges = [ // 边列表,每个元素表示一条边,包含起点、终点和权重
{u: 0, v: 1, weight: 1},
{u: 0, v: 2, weight: 3},
{u: 1, v: 2, weight: 2},
{u: 1, v: 3, weight: 4},
{u: 2, v: 3, weight: 5}
];
console.log(kruskal(n, edges)); // 输出最小生成树的权重和,应为6
在这个实现中,我们首先定义了一个UnionFind类,用于维护并查集数据结构,支持查找和合并操作。然后,我们实现了kruskal函数,该函数接受顶点数量和边列表作为参数,返回最小生成树的权重和。在函数内部,我们首先对边列表按照权重进行排序,然后依次遍历每条边,如果这条边连接的两个顶点不在同一个连通块中,就将它们合并,并将这条边的权重加入结果中。当已经选择了n-1条边时,就结束循环,返回结果。如果遍历完所有边后仍然无法选择n-1条边,说明图不连通,无法生成最小生成树,返回null。
浙公网安备 33010602011771号