哈夫曼编码
来源:互联网 发布:斧子演示 知乎 编辑:程序博客网 时间:2024/06/16 23:14
先生成哈夫曼树,然后遍历树得到编码。
生成哈夫曼树:
每个字符对应一个权重初始化为一个节点,所有节点按照权重排序,然后选出两个权重最小的两个节点和创建一个新的节点,选出的两个节点作为新创建节点的左右孩子节点,新节点的权值为两个孩子节点的和,然后将新节点放入原来的没选取出的节点中重新排序,重复上述步骤,直到只剩下一个节点,也就是这棵哈夫曼树的根节点了。
最后从根节点开始遍历树,统计从根节点到叶节点的路劲对应的编码就能得到最终结果了。
创建新节点放入剩余节点重新排序这一步骤的时候,如果字符量少可以选择常量时间很低的插入排序,如果数据量大可以利用归并排序的原理,原始节点排序后入队列A,新创建一个队列B,将新创建的节点入队B,因为后创建的节点的权值一定比先创建的节点的权值更大,所以依次入队的话将队列元素将按从小到大排列,之后每次找最小值就只需要较队头元素然后选中较小的一个出队。
代码:
#include<iostream>#include<string>#include<algorithm>#include<cstring>using namespace std;#define mem(x) memset(x,0,sizeof(x))#define MaxN 30//存放剩余没被选出的节点信息struct sum{ double s; int num; bool operator < (sum x){ return s<x.s; }}tree[MaxN+5];//存放之后每个新创建节点的孩子节点和自身编号信息//也是由这个来存放树struct parent{ int num; int left; int right;}par[2*MaxN+10];//存放每个字符信息struct data{ char character; double value; string code; //存放每个字符的哈夫曼编码}A[MaxN+5];//遍历树并找到编码void FindCode(int num,string code=""){ if(par[num].left!=0){ FindCode(par[num].left,code+'0'); } if(par[num].right!=0){ FindCode(par[num].right,code+'1'); } if((par[num].left+par[num].right)==0){ A[num].code=code; }}void huffman(int N){ sum temp; mem(A);mem(par);mem(tree); for(int i=1;i<=N;i++){ cin>>A[i].character>>A[i].value; tree[i].num=i; tree[i].s=A[i].value; par[i].num=i; } //建树 sort(tree+1,tree+N+1); for(int i=1;i<=N-1;i++){ par[N+i].left=tree[i].num; par[N+i].right=tree[i+1].num; tree[i+1].s+=tree[i].s; tree[i+1].num=N+i; int j=i+1; temp=tree[i+1]; //下面是排序 因为数据量小所以选择常量时间低的插入排序 //如果编码数据多可以利用归并排序的原理进行排序优化时间复杂度 //也就是合并后的节点值按顺序放入一个新的队列 这个队则会有序 连续两次选出两个队列对头元素中较小的一个 while(temp.s>tree[j+1].s&&j<N){ tree[j]=tree[j+1]; j++; } tree[j]=temp; } //下面这个函数用来递归遍历树并记录下正确编码 FindCode(2*N-1);}//测试用的主函数int main(){ int num; cout<<"how many characters do you want to encoding? please input a number."<<endl; cin>>num; cout<<"please input all characters and weight value."<<endl; huffman(num); cout<<"ans:"<<endl; for(int i=1;i<=num;i++){ cout<<A[i].character<<":"<<A[i].code<<endl; }}
阅读全文
0 0
- 信源编码---哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 哈夫曼编码
- 归并排序
- [题解]NOIP2015提高组の题解集合
- codevs1116 四色问题
- ThinkPHP框架访问文件提示No input file specified解决方案
- MongoDB 集合字段匹配查询方法
- 哈夫曼编码
- javascript动态添加网页组件
- 编程的那些事儿(一)
- Linux IPC 3 之 信号量
- 僵尸进程和孤儿进程
- C语言简单复习
- Python学习之初始(五)
- 怎样才能赚到钱系列(一)
- js数组