[大话数据结构] 6.12.3 赫夫曼编码
2014-06-06 19:09
239 查看
今天抽时间看了一下赫夫曼编码,感觉挺有意思。那就做个小总结。
赫夫曼树:带全路径长度WPL最小的二叉树称作赫夫曼树。具题看大话数据结构 200页 或 百度~
赫夫曼编码:按照叶子结点的权值从小到大来构造一棵赫夫曼树。 规定赫夫曼树的做分支代表0,右分支代表1,
则从根节点到叶子结点所经过的路径分支组成的序列称作赫夫曼编码。具题看大话数据结构 207页 或 百度~
我们来看下书上的例子:
假设六个字母的频率为 A 27 ,B 8,C 15,D 30,E 30,F 5,合起来正好是100%。
我们把频率低的看为结点权值小。那么我们就可以构造出一颗赫夫曼树。
可以用 结构体数组 和 优先队列 模拟建树。
具体实现看代码吧,已经在代码后面加上详细的注释了~~
赫夫曼树:带全路径长度WPL最小的二叉树称作赫夫曼树。具题看大话数据结构 200页 或 百度~
赫夫曼编码:按照叶子结点的权值从小到大来构造一棵赫夫曼树。 规定赫夫曼树的做分支代表0,右分支代表1,
则从根节点到叶子结点所经过的路径分支组成的序列称作赫夫曼编码。具题看大话数据结构 207页 或 百度~
我们来看下书上的例子:
假设六个字母的频率为 A 27 ,B 8,C 15,D 30,E 30,F 5,合起来正好是100%。
我们把频率低的看为结点权值小。那么我们就可以构造出一颗赫夫曼树。
可以用 结构体数组 和 优先队列 模拟建树。
具体实现看代码吧,已经在代码后面加上详细的注释了~~
#include <stdio.h> #include <string.h> #include <queue> using namespace std; int ans = 0, flag; char chc[1000]; struct ak { int qz; //权值 char ch; //字母 int arr; //元素所在数组下标 bool operator < (const ak &a) const { return a.qz < qz; //优先队列重载操作符 } }temp; priority_queue<ak> pq; struct Node { int dir[2]; //结点左孩子和右孩子 char cc; //字母 }s[100000]; int gao() { while(1) { int siz = pq.size(); int father = ans++; s[father].cc ='$'; int cnt = 0; for(int i = 0; i < 2 ; i++) { s[father].dir[i] = -1; if(i < siz) { temp = pq.top(); pq.pop(); cnt += temp.qz; if(temp.arr == -1) { s[ans].cc = temp.ch; s[ans].dir[0] = s[ans].dir[1] = -1; s[father].dir[i] = ans++; } else { s[father].dir[i] = temp.arr; } } } temp.qz = cnt; temp.ch = '$'; temp.arr = father; pq.push(temp); if(pq.size() == 1) { return father; //如果队列元素只剩一个了,函数调用结束。 } } } void init() { temp.arr = -1; temp.qz = 27, temp.ch = 'A'; pq.push(temp); temp.qz = 8, temp.ch = 'B'; pq.push(temp); temp.qz = 15, temp.ch = 'C'; pq.push(temp); temp.qz = 15, temp.ch = 'D'; pq.push(temp); temp.qz = 30, temp.ch = 'E'; pq.push(temp); temp.qz = 5, temp.ch = 'F'; pq.push(temp); } int dir(int x, int deep) { int k = (chc[deep] == '0' ? 0 : 1); //解码过程,如果当前数字是0那么往左走,否则往右 if(s[x].dir[k] != -1) //如果有子结点,那么继续递归 { return dir(s[x].dir[k], deep+1); } else //如果没有子结点,递归结束 { printf("%c", s[x].cc); return deep-1; } } int main() { init(); //把大话数据结构P206页的6个字母和频率放入优先队列中 int kk = gao(); //根据字母和频率构造赫夫曼树 gets(chc); flag = 0; int coun = 0; for(; flag < strlen(chc); flag++, coun++) { flag = dir(kk, flag); } puts(""); return 0; }
相关文章推荐
- 《大话数据结构》树以及赫夫曼编码的例子
- 赫夫曼编码
- 《大话数据结构》第9章 排序 9.4 简单选择排序
- 《大话数据结构》简体中文版勘误
- 建立赫夫曼树以及求赫夫曼编码
- 《大话数据结构》--学习笔记2
- 读书笔记-大话数据结构(1)
- 《大话数据结构》读书笔记(五)
- 《大话数据结构》笔记之 第二章 算法
- 大话数据结构-图
- 大话数据结构-排序
- huffman(赫夫曼编码)之C/C++实现
- 《算法导论》笔记 第16章 16.3 赫夫曼编码
- 大话数据结构-第三章之线性表&链表
- 数据结构之共享栈(顺序存储)—改编《大话数据结构》
- [大话数据结构]线性表之单链表结构和顺序存储结构
- 大话数据结构——二叉树的建立于遍历
- 已知某系统在通信联络中只可能出现8种字符,其概率分别为0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11,试编写算法求其赫夫曼编码。
- 《大话数据结构》第1章 数据结构绪论 1.2 你数据结构怎么学的?