题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1053

分析:这道题目是一道很典型的哈夫曼树问题,哈夫曼树(见百度百科)总之一句话,主要作用就是用来解决压缩编码问题,相信学过离散数学的同学都应该学过这个神奇的数据结构。

(1)建立哈夫曼树节点结构体

typedef struct Huffman_trie
{int deep;//深度int freq;//频度(即哈夫曼树中的权重)Huffman_trie *left,*right;//优先权队列中用于排序比较的方法,不懂的建议先学一学优先权队列    friend bool operator<(Huffman_trie a,Huffman_trie b)return a.freq>b.freq;
}Huffman_trie;

(2)首先我们把读入的字符串进行预处理,按照字符分别放入对应的节点中,同时记录其出现频率,count_num记录字符出现次数,同时放入哈夫曼节点中

        len = strlen(str);str[len]='!';sort(str,str+len);count_num=1;index=0;for(int i=1;i<=len;i++){if(str[i]!=str[i-1]){trie[index++].freq=count_num;count_num=1;}else count_num++;}    

(3)用一个优先权队列存储节点,每次取出频率最小的两个节点,合并节点并把其合并后的节点放入优先权队列中,一直合并到队列中只剩下最后一个节点,把其作为根节点。(这正是哈夫曼树建立的关键,这个地方一定要理解)

root = (Huffman_trie*)malloc(sizeof(Huffman_trie));for(int i=0;i<index;i++)pq.push(trie[i]);while(pq.size()>1){Huffman_trie *h1 = (Huffman_trie*)malloc(sizeof(Huffman_trie));*h1 = pq.top();pq.pop();Huffman_trie *h2 = (Huffman_trie*)malloc(sizeof(Huffman_trie));*h2 = pq.top();pq.pop();Huffman_trie h3;h3.left=h1;h3.right=h2;h3.freq=h1->freq+h2->freq;pq.push(h3);}*root = pq.top();

(4)哈夫曼树建立完之后就是求其编码长度的问题了,这时候就是遍历该树的问题了,方法有很多,可以深度遍历,也可以广度遍历。这里采用广度遍历,同时借助于一个queue进行的。

queue<Huffman_trie>q;q.push(*root);while(!q.empty()){Huffman_trie ht=q.front();q.pop();if(ht.left!=NULL){ht.left->deep=ht.deep+1;q.push(*ht.left);}if(ht.right!=NULL){ht.right->deep=ht.deep+1;q.push(*ht.right);}if(!ht.left&&!ht.right)sum+=ht.deep*ht.freq;}

(5)剩下的就很简单了,不做过多的赘述。

整个题的全部代码

#include <iostream>
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;typedef struct Huffman_trie
{int deep;//深度int freq;//频度(即哈夫曼树中的权重)Huffman_trie *left,*right;//优先权队列中用于排序比较的方法,不懂的建议先学一学优先权队列friend bool operator<(Huffman_trie a,Huffman_trie b)return a.freq>b.freq;
}Huffman_trie;Huffman_trie trie[300];//哈夫曼树节点
Huffman_trie *root;
int len,count_num,index,sum;
priority_queue<Huffman_trie> pq;void huffman()
{sum=0;root = (Huffman_trie*)malloc(sizeof(Huffman_trie));for(int i=0;i<index;i++)pq.push(trie[i]);while(pq.size()>1){Huffman_trie *h1 = (Huffman_trie*)malloc(sizeof(Huffman_trie));*h1 = pq.top();pq.pop();Huffman_trie *h2 = (Huffman_trie*)malloc(sizeof(Huffman_trie));*h2 = pq.top();pq.pop();Huffman_trie h3;h3.left=h1;h3.right=h2;h3.freq=h1->freq+h2->freq;pq.push(h3);}*root = pq.top();pq.pop();root->deep=0;queue<Huffman_trie>q;q.push(*root);while(!q.empty()){Huffman_trie ht=q.front();q.pop();if(ht.left!=NULL){ht.left->deep=ht.deep+1;q.push(*ht.left);}if(ht.right!=NULL){ht.right->deep=ht.deep+1;q.push(*ht.right);}if(!ht.left&&!ht.right)sum+=ht.deep*ht.freq;}}
int main()
{char str[1000];while(scanf("%s",str)!=EOF&&strcmp(str,"END")!=0){len = strlen(str);str[len]='!';sort(str,str+len);count_num=1;index=0;for(int i=1;i<=len;i++){if(str[i]!=str[i-1]){trie[index++].freq=count_num;count_num=1;}else count_num++;}if(index==1)printf("%d %d 8.0\n",len*8,len);else{huffman();printf("%d %d %.1lf\n",len*8,sum,len*8*1.0/sum);}}return 0;
}

本文转自NewPanderKing51CTO博客,原文链接:http://www.cnblogs.com/newpanderking/archive/2012/11/14/2769367.html ,如需转载请自行联系原作者

hdu 1053 Entropy (哈夫曼树)相关推荐

  1. HDU1053 Entropy 哈夫曼树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1053 认真读题,别怕题长,此题考查的就是哈夫曼树并求出最小编码值,注意每一次要将数组清0,否则会出错! ...

  2. 两个队列+k叉哈夫曼树 HDU 5884

    1 // 两个队列+k叉哈夫曼树 HDU 5884 2 // camp题解: 3 // 题意:nn个有序序列的归并排序.每次可以选择不超过kk个序列进行合并,合并代价为这些序列的长度和.总的合并代价不 ...

  3. 【HDU - 5884】Sort(k叉哈夫曼树,优化tricks,两个队列代替优先队列)

    题干: Recently, Bob has just learnt a naive sorting algorithm: merge sort. Now, Bob receives a task fr ...

  4. 哈夫曼树:HDU5884-Sort(队列、哈夫曼树)

    Sort Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) 题目链接:http://ac ...

  5. K叉哈夫曼树构造方法 O(N)

    带权路径:是树中所有的叶结点的权值乘上其到根结点的路径长度. 哈夫曼树就是带权路径最小的树. 有n个数(即n个叶子节点),构造k叉(k>=2)哈夫曼树的方法: 构造哈夫曼树,其实就是不停的&qu ...

  6. labview霍夫曼树_霍夫曼树的应用

    霍夫曼树的具体证明在离散数学书上有,我总结大意如下: 我们平常查询单词的时候,总会有一些词查询的频率高,一些词查询的频率低,如果建立一棵树来查询,应该使那些经常查询的码(信息经过无损压缩后)的深度尽量 ...

  7. Python---哈夫曼树---Huffman Tree

    今天要讲的是天才哈夫曼的哈夫曼编码,这是树形数据结构的一个典型应用. !!!敲黑板!!!哈夫曼树的构建以及编码方式将是我们的学习重点. 老方式,代码+解释,手把手教你Python完成哈夫曼编码的全过程 ...

  8. 优先级队列实现哈夫曼树的编码和译码

    //优先级队列实现的哈夫曼树的编码和译码 #include<iostream> #include<queue> #include<string> using nam ...

  9. 数据结构与算法(6-5)二叉树的应用--哈夫曼树与哈夫曼编码

    目录 哈夫曼编码(最优二叉树) 一.优势:缩短电文长度 二.思想: 三.过程: 四.图解实现过程: 五.总代码 哈夫曼编码(最优二叉树) 一.优势:缩短电文长度 二.思想: 获取每个字符出现的频率,用 ...

最新文章

  1. window COM调试2[转]
  2. 基于JSP/SERVLET学生管理系统
  3. 中国再生金属行业发展前景及投资策略研究报告2021版
  4. 2017计算机科技贡献奖,2017年度科技创新贡献奖评审结果公布
  5. Oracle hint手动优化
  6. 【转载,留作参考】mysql 截取字符串以及mysql update select
  7. 四叉树算法原理与实现
  8. 阅读札记:创新与思维范式
  9. cpu烤机温度测试软件,ATX2.0与ATX3.0机箱烤机温度对比测试,竖装显卡真的会把风挡死...
  10. 龙芯源码编译mysql_使用源码包在龙芯2F上安装mysql
  11. JS设计模式与开发实践
  12. [GIS热点] 3S技术集成-新技术革命下集成模式
  13. js下拉列表二级联动
  14. DQN的e-greedy策略理解
  15. 如何用sql语句查询年龄最小或最大的信息
  16. Excel的VBA使用
  17. 初中英语语法(013)-动词
  18. ISTQB TM考点总结之第三章
  19. 认识微服务(七)之 Zuul 网关
  20. C++数据结构 航空客运订票系统

热门文章

  1. redux 入门到实践
  2. JAVA EE Eclipse下配置Tomcat服务器
  3. 《精通Linux设备驱动程序开发》——1.5 Linux发行版
  4. Python语言精要---上
  5. mysql 必须掌握的工具pt-query-digest安装
  6. Timestamp、String、Date之间的转换
  7. 逐行计算、逐行递延、逐行更新
  8. 中tile函数_HelpGirlFriend 系列 --- tensorflow 中的张量运算思想
  9. Kubernetes — 容器与镜像
  10. Kubernetes — CNI 规范