霍夫曼编码

原创 2015年11月18日 10:08:14

Description
对输入的英文大写字母序列进行统计概率,然后构建Huffman树,输出按照概率降序排序输出Huffman编码。
 
Input

第一行是大写字母个数n(0<n<=100)

第二行为n个字母,中间以一个空格分隔。
 
Output

假设输入中共有m个不同的字母,按照出现概率降序输出,每个字母单独一行输出。格式如下:

字母1 出现次数 Huffman编码
字母2 出现次数 Huffman编码
字母3 出现次数 Huffman编码
字母m 出现次数 Huffman编码
 
Sample Input
Copy sample input to clipboard
10
S S U U U S U L U U
Sample Output
U 6 1
S 3 01
L 1 00

题目分析

构造哈夫曼树非常简单,每次将所有节点排序,用一个节点替换两个频率最低的节点,新节点的频率就是这两个节点的频率之和。这样,新节点就是两个被替换节点的父节点了。如此循环,直到只剩一个节点(树根)。
注意使被替换节点中频率低的为左孩子,高者为右孩子

为了适应题目需求,定义了如下结构体
struct Node {
  int value;    // 记录频率
  char c;       // 记录字符
  std::string code;   // 记录编码
  Node* l;            // 左孩子
  Node* r;            // 右孩子
  Node(int num, int index) { };   //num为频率, index用来确定是那个字符
} *nodes[26];
在按照上面方法构造哈夫曼树的时候,同时将所有的叶子节点(左右孩子为NULL)按频率从低到高(左孩子先入栈)入栈
当只剩下一个节点时,从上到下确定每个节点的编码
if (root->l != NULL) {
  root->l->code = root->code + "0";
  dfs(root->l);
}同理确定右孩子的编码
最后按要求输出栈内节点的值

#include <iostream>
#include <stack>
#include <algorithm>
#include <memory.h>

struct Node {
  int value;
  char c;
  std::string code;
  Node* l;
  Node* r;
  Node(int num, int index) {
    value = num;
    c = 'A' + index;
    code = "";
    l = r = NULL;
  }
} *nodes[26];

bool com(Node* a, Node* b) {
  return a->value > b->value;
}

void dfs(Node* root) {
  if (root->l != NULL) {
    root->l->code = root->code + "0";
    dfs(root->l);
  }
  if (root->r != NULL) {
    root->r->code = root->code + "1";
    dfs(root->r);
  }
}

int main()
{
  int num;
  std::cin >> num;
  int arr[26];
  memset(arr, 0, sizeof(arr));
  char temp;
  int count = 0;
  for (int i = 0; i < num; ++i) {
    std::cin >> temp;
    if (arr[temp-'A'] == 0)
      count++;
    arr[temp-'A']++;
  }
//std::cout << count << std::endl;
  int index = 0;
  for (int i = 0; i < 26; ++i) {
    if (arr[i] > 0) {
      nodes[index++] = new Node(arr[i], i);
    }
  }

  std::stack<Node*> s;
  while (count != 1) {
    std::sort(nodes, nodes+count, com);
    if (nodes[count-1]->l == NULL && nodes[count-1]->r == NULL)
      s.push(nodes[count-1]);
    if (nodes[count-2]->l == NULL && nodes[count-2]->r == NULL)
      s.push(nodes[count-2]);
    Node* father = new Node(nodes[count-1]->value + nodes[count-2]->value, 0);
    father->l = nodes[count-1];
    father->r = nodes[count-2];
    nodes[count-2] = father;
    count--;
  }
//std::cout << count << std::endl;
  dfs(nodes[0]);
//std::cout << "coding end" << std::endl;
  while (!s.empty()) {
    std::cout << s.top()->c << " " << s.top()->value << " " << s.top()->code << std::endl;
    s.pop();
  }
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

香农,霍夫曼编码

  • 2015年12月14日 20:35
  • 36KB
  • 下载

霍夫曼编码

  • 2015年07月14日 21:46
  • 3KB
  • 下载

算法设计与分析--霍夫曼树编码(C++实现)

问题描述: 设需要编码的字符集为{d1, d2, …, dn},它们出现的频率为{w1, w2, …, wn},应用哈夫曼树构造最短的不等长编码方案。 Huffman算法: ...
  • wwj_748
  • wwj_748
  • 2013年05月27日 19:29
  • 8353

霍夫曼编码解码

  • 2013年05月12日 14:20
  • 6KB
  • 下载

霍夫曼编码及译码

  • 2014年05月17日 12:22
  • 5KB
  • 下载

JPEG 编解码器 霍夫曼编码

arm11中的JPEG 编解码器 霍夫曼编码是一种被广泛应用而且非常有效的数据压缩技术,根据待压缩数据的特征,一个可压缩掉20%~90%。这里考虑的数据指的是字符串序列。要理解霍...

霍夫曼编码对图像压缩解压

  • 2017年07月22日 09:13
  • 11.55MB
  • 下载

霍夫曼(huffman)编码C++程序

  • 2010年04月21日 17:22
  • 190KB
  • 下载

霍夫曼编码压缩算法 - 博客 - 伯乐在线

霍夫曼编码压缩算法 - 博客 - 伯乐在线 前两天发布那个rsync算法后,想看看数据压缩的算法,知道一个经典的压缩算法Huffman算法。相信大家应该听说过 David Huffman 和他的压缩...

霍夫曼编码(C)

  • 2011年12月03日 21:25
  • 2KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:霍夫曼编码
举报原因:
原因补充:

(最多只允许输入30个字)