问题描述:给定一个带权无向图,找到一棵包含所有节点的树,使得树的边权重和最小
贪心策略
- 从任一节点开始,选择连接到树中的权重最小的边
- 直到所有节点都包含在树中
实现代码
class PriorityQueue {
constructor() {
this.values = [];
}
enqueue(val, priority) {
this.values.push({ val, priority });
this.sort();
}
dequeue() {
return this.values.shift();
}
sort() {
this.values.sort((a, b) => a.priority - b.priority);
}
}
function prim(graph) {
const nodes = Object.keys(graph);
const pq = new PriorityQueue();
const startNode = nodes[0];
const mst = [];
const visited = new Set();
pq.enqueue(startNode, 0);
while (pq.values.length) {
let { val: currentNode } = pq.dequeue();
if (visited.has(currentNode)) continue;
visited.add(currentNode);
for (let neighbor in graph[currentNode]) {
if (!visited.has(neighbor)) {
pq.enqueue(neighbor, graph[currentNode][neighbor]);
}
}
if (currentNode !== startNode) mst.push(currentNode);
}
return mst;
}
// 测试代码
const graph = {
A: { B: 2, C: 3 },
B: { A: 2, C: 1, D: 1 },
C: { A: 3, B: 1, D: 4, E: 5 },
D: { B: 1, C: 4, E: 2 },
E: { C: 5, D: 2 }
};
console.log(prim(graph)); // 输出: 最小生成树的节点