请用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

posted @ 2024-12-27 09:31  王铁柱6  阅读(22)  评论(0)    收藏  举报