js 贪心算法(最小生成树问题、霍夫曼编码问题的)

1. 最小生成树问题(Minimum Spanning Tree Problem):

假设有一个无向连通图,图中的每个边都有一个权重。最小生成树问题要求找到一个包含图中所有顶点的树,使得树的边的权重之和最小。

以下是使用Prim算法求解最小生成树问题的示例代码:

function prim(graph) {
  const n = graph.length;
  const visited = Array(n).fill(false);
  const key = Array(n).fill(Number.MAX_VALUE);  // 记录每个顶点的最小权重
  const parent = Array(n).fill(-1);  // 记录每个顶点的父节点

  key[0] = 0;  // 从第一个顶点开始构建最小生成树
  for (let i = 0; i < n - 1; i++) {
    const u = findMinKey(key, visited);
    visited[u] = true;

    for (let v = 0; v < n; v++) {
      if (graph[u][v] !== 0 && !visited[v] && graph[u][v] < key[v]) {
        key[v] = graph[u][v];
        parent[v] = u;
      }
    }
  }

  return parent;
}

function findMinKey(key, visited) {
  const n = key.length;
  let minKey = Number.MAX_VALUE;
  let minIndex = -1;

  for (let v = 0; v < n; v++) {
    if (!visited[v] && key[v] < minKey) {
      minKey = key[v];
      minIndex = v;
    }
  }

  return minIndex;
}

const graph = [
  [0, 2, 0, 6, 0],
  [2, 0, 3, 8, 5],
  [0, 3, 0, 0, 7],
  [6, 8, 0, 0, 9],
  [0, 5, 7, 9, 0]
];

console.log(prim(graph));  // 输出:[ -1, 0, 1, 0, 1 ]

以上示例中使用了Prim算法来求解最小生成树问题。算法的核心思想是从一个顶点开始,每次选择与当前生成树距离最小的顶点,并加入到生成树中,直到生成树包含所有顶点为止。`prim` 函数返回一个数组 `parent`,表示每个顶点的父节点,从而构建最小生成树。

2. 霍夫曼编码问题(Huffman Coding Problem):

霍夫曼编码是一种变长编码方式,根据字符出现的频率来构建一个前缀码树,使得频率高的字符具有较短的编码,而频率低的字符具有较长的编码。下面是使用贪心算法解决霍夫曼编码问题的实例:

class Node {
  constructor(value, freq) {
    this.value = value;
    this.freq = freq;
    this.left = null;
    this.right = null;
  }
}

function buildHuffmanCodingTree(arr) {
  const n = arr.length;
  const pq = new PriorityQueue((a, b) => a.freq - b.freq);

  for (let i = 0; i < n; i++) {
    pq.enqueue(new Node(arr[i].value, arr[i].freq));
  }

  while (pq.size() > 1) {
    const left = pq.dequeue();
    const right = pq.dequeue();
    const parent = new Node(null, left.freq + right.freq);
    parent.left = left;
    parent.right = right;
    pq.enqueue(parent);
  }

  return pq.dequeue();
}

function buildHuffmanCodeTable(root) {
  const codeTable = {};

  function traverse(node, code) {
    if (node.value) {
      codeTable[node.value] = code;
    } else {
      traverse(node.left, code + "0");
      traverse(node.right, code + "1");
    }
  }

  traverse(root, "");

  return codeTable;
}

const arr = [
  { value: "a", freq: 3 },
  { value: "b", freq: 6 },
  { value: "c", freq: 2 },
  { value: "d", freq: 1 }
];

const root = buildHuffmanCodingTree(arr);
const codeTable = buildHuffmanCodeTable(root);

console.log("Huffman Code Table:");
for (let key in codeTable) {
  console.log(key + ": " + codeTable[key]);
}

在上述示例中,我们首先创建了一个 `Node` 类用于表示霍夫曼树的节点,其中 `value` 存储字符,`freq` 存储频率,`left` 和 `right` 存储左子节点和右子节点。

然后,我们使用一个优先队列(Priority Queue)来按照频率将节点进行排序。在构建霍夫曼编码树的过程中,我们每次从队列中取出频率最小的两个节点,将它们合并为一个新的父节点,并将父节点重新插入队列中,直到队列中只剩下一个节点,即为根节点。

最后,我们使用递归的方式遍历树,生成每个字符的霍夫曼编码,并将编码存储在 `codeTable` 中。

以上示例中,我们以字符 `'a'`、`'b'`、`'c'` 和 `'d'` 的频率为 `{ value: "a", freq: 3 }`、`{ value: "b", freq: 6 }`、`{ value: "c", freq: 2 }` 和 `{ value: "d", freq: 1 }`,构建了霍夫曼树,并生成了每个字符对应的霍夫曼编码。

输出结果为:

Huffman Code Table:
a: 01
b: 1
c: 00
d: 001

以上是一个使用贪心算法解决霍夫曼编码问题的实例。通过贪心策略,每次选择当前状态下的最优解来构建编码树,从而得到每个字符的最优编码。
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值