赫夫曼\哈夫曼\霍夫曼编码 (Huffman Tree)
哈夫曼树
给定n个权值作为n的叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
哈夫曼编码(Huffman Coding)
又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)。
应用举例
哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。 在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称“熵编码法”),用于数据的无损耗压缩。这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。
构造Huffman tree


过程:
1、输入字符关键字以及对应的频率。
2、根据关键字的频率构造最优二叉树
(1)借助于STL的优先队列 :priority_queue<type, vector<type>,cmp>que; 其中type为优先队列的类型,比如说int, double, 也可以将结构体作为类型。vector它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。借助于vector可以很轻松的解决一些问题。cmp为定义的优先队列的出队规则,给出博客http://www.cnblogs.com/buptLizer/archive/2011/09/11/2173708.html大家可以参考来理解优先队列的使用。以及其中常用的操作que.pop(), que.push(), que.top(), que.size()等...
(2)构造最优二叉搜索树:在有了最优二叉搜索树的帮助之后,对于构建搜索树很容易。上面的图很清楚的讲解了构造的过程,每次取出频率最小的两个形成一个子树,将其频率相加之后再放入优先队列之中,直到队列中元素个数为0。在操作过程中需要遵守最优二叉搜索树的定义,左孩子小于父节点,右孩子大于父节点。
(3)递归遍历二叉树:遍历中只需要记住,向左遍历那么前缀码为0,向右为1.
亲测代码:
#include <bits/stdc++.h>
#define max_size 10010
char c[max_size];
double f[max_size]; using namespace std;
typedef struct node
{
char ch;
double freq;
node *lchild;
node *rchild;
node(char c=,double f=,node *l=NULL,node *r=NULL):
ch(c),freq(f),lchild(l),rchild(r) {}
};
typedef struct cmp
{
bool operator()(node*&a,node*&b)
{
return a->freq>b->freq;
}
};
node* createTree(int n)
{
priority_queue<node*,vector<node*>,cmp>que;
for(int i=; i<=n; i++)
{
cin>>c[i]>>f[i];
que.push(new node(c[i],f[i]));
}
while(que.size()>)
{
node *l=que.top();
que.pop();
node *r=que.top();
que.pop();
node *newnode=new node(,l->freq+r->freq,l,r);
que.push(newnode);
}
return que.top();
} void printInfo(const node *tree,string code)
{
if(tree->lchild==NULL&&tree->rchild==NULL)
{
cout<<tree->ch<<":"<<code<<" ";
return;
}
if(tree->lchild!=NULL)printInfo(tree->lchild,code+'');
if(tree->rchild!=NULL)printInfo(tree->rchild,code+'');
}
void deleteTree(node *tree)
{
if(tree->lchild!=NULL)deleteTree(tree->lchild);
if(tree->rchild!=NULL)deleteTree(tree->rchild);
delete(tree);
}
int main()
{
int n;
priority_queue<node*,vector<node*>,greater<node*> >que;
while(~scanf("%d",&n))
{
node *tree=createTree(n);
printf("Huffman code:\n");
printInfo(tree,"");
}
}
输入数据以及运行结果:

赫夫曼\哈夫曼\霍夫曼编码 (Huffman Tree)的更多相关文章
- opencv —— HoughLines、HoughLinesP 霍夫线变换原理(标准霍夫线变换、多尺度霍夫线变换、累积概率霍夫线变换)及直线检测
霍夫线变换的原理 一条直线在图像二维空间可由两个变量表示,有以下两种情况: ① 在笛卡尔坐标系中:可由参数斜率和截距(k,b)表示. ② 在极坐标系中:可由参数极经和极角(r,θ)表示. 对于霍夫线变 ...
- Java数据结构(十二)—— 霍夫曼树及霍夫曼编码
霍夫曼树 基本介绍和创建 基本介绍 又称哈夫曼树,赫夫曼树 给定n个权值作为n个叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称为最优二叉树 霍夫曼树是带权路径长度最短的树,权值较 ...
- word2vec 中的数学原理二 预备知识 霍夫曼树
主要参考: word2vec 中的数学原理详解 自己动手写 word2vec 编码的话,根是不记录在编码中的 这一篇主要讲的就是霍夫曼树(最优二叉树)和编码. ...
- opencv —— HoughCircles 霍夫圆变换原理及圆检测
霍夫圆变换原理 霍夫圆变换的基本原理与霍夫线变换(https://www.cnblogs.com/bjxqmy/p/12331656.html)大体类似. 对直线来说,一条直线能由极径极角(r,θ)表 ...
- OpenCV中的霍夫线变换和霍夫圆变换
一.霍夫线变换 霍夫线变换是OpenCv中一种寻找直线的方法,输入图像为边缘二值图. 原理: 一条直线在图像二维空间可由两个变量表示, 例如: 1.在 笛卡尔坐标系: 可由参数: (m,b) 斜率和截 ...
- C# 霍夫曼二叉树压缩算法实现
知道有的人比较懒,直接贴全部代码. 一开始一次性Code完了压缩部分代码.只调试了2,3次就成功了. 一次性写150行代码,没遇到什么bug的感觉还是蛮爽的. 写解压代码,才发现压缩代码有些细节问题. ...
- 基于python的二元霍夫曼编码译码详细设计
一.设计题目 对一幅BMP格式的灰度图像(个人证件照片)进行二元霍夫曼编码和译码 二.算法设计 (1)二元霍夫曼编码: ①:图像灰度处理: 利用python的PIL自带的灰度图像转换函数,首先将彩色图 ...
- 霍夫曼编码(Huffman Coding)
霍夫曼编码(Huffman Coding)是一种编码方法,霍夫曼编码是可变字长编码(VLC)的一种. 霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符 ...
- CF 463A && 463B 贪心 && 463C 霍夫曼树 && 463D 树形dp && 463E 线段树
http://codeforces.com/contest/462 A:Appleman and Easy Task 要求是否全部的字符都挨着偶数个'o' #include <cstdio> ...
随机推荐
- WPF DataGrid绑定及列居中
基本的数据绑定 把集合的字段(属性)绑定在DataGrid的Binding属性就能将数据绑定列表 public class CashItem { public int Value { get; set ...
- MVC5+EF6 入门完整教程13 -- 动态生成多级菜单
稍微有一定复杂性的系统,多级菜单都是一个必备组件. 本篇专题讲述如何生成动态多级菜单的通用做法. 我们不用任何第三方的组件,完全自己构建灵活通用的多级菜单. 需要达成的效果:容易复用,可以根据mode ...
- aspNet各种模块介绍
For browsers that do not support HTML5, you can use Modernizr. Modernizr is an open-source JavaScrip ...
- Service随系统启动运行
Android系统启动时,会发出android.intent.action.BOOT_COMPLETED广播,定义一个类继承自BroadcastReceiver,监听该广播,并在收到该广播时启动Ser ...
- Scalaz(9)- typeclass:checking instance abiding the laws
在前几篇关于Functor和Applilcative typeclass的讨论中我们自定义了一个类型Configure,Configure类型的定义是这样的: case class Configure ...
- jquery刷新页面
下面介绍全页面刷新方法:有时候可能会用到 window.location.reload()刷新当前页面. parent.location.reload()刷新父亲对象(用于框架) opener.loc ...
- 七个结构模式之装饰者模式(Decorator Pattern)
定义: 使用组合的方法,动态给一个类增加一些额外的功能,避免因为使用子类继承而导致类继承结构复杂.并且可以保持和被装饰者同一个抽象接口,从而使客户端透明. 结构图: Component:抽象构件类,定 ...
- 七个结构模式之桥接模式(Bridge Pattern)
问题: 当存在多个独立的变化维度时,如果仍采用多层继承结构,会急剧的增加类的个数,因此可以考虑将各个维度分类,使他们不相互影响. 定义: 将抽象部分与它的实现部分进行分离,抽象部分只保留最为本质的部分 ...
- 创业小坑:内网域名 在windows下能nslookup,但ping不通,也无法访问。而在linux下正常。
使用巴法络(BUFFALO )LS-XL 网络硬盘盒开启了FTP服务,IP是172.16.0.21 在windows和linux上,都可以访问ftp://172.16.0.21,现在想使用域名访问,便 ...
- liMarquee演示12种不同的无缝滚动效果
很实用的一款liMarquee演示12种不同的无缝滚动效果 在线预览 下载地址 实例代码 <!DOCTYPE html> <html lang="zh-CN"&g ...