Huffman 编码树

Huffman 编码树Huffman 编码树像 SCAII 这样即那个每个字符表示为一个 7 为二进制的序列的编码方式称为定长编码 它们采用同样数目的二进制位表示消息中的一个字符 与之相对应的是变长编码 即用可变的二进制位数表示不同的字符 一般而言 如果在我们的消息中 某写符号出现得比较频繁 而另一些比较少见 那么就可以通过为这些出现比较频繁的字符指定比较短的二进制位编码来达到节省空间的目的 但是采用二

Huffman 编码树

像SCAII这样即那个每个字符表示为一个7为二进制的序列的编码方式称为定长编码,它们采用同样数目的二进制位表示消息中的一个字符.与之相对应的是变长编码,即用可变的二进制位数表示不同的字符.

一般而言,如果在我们的消息中,某写符号出现得比较频繁,而另一些比较少见,那么就可以通过为这些出现比较频繁的字符指定比较短的二进制位编码来达到节省空间的目的.

但是采用二进制编码有一个困难,它需要在读二进制序列是判断合适到达了一个字符的结束.解决这一问题的方法可以在每个字母后面用一个特殊分隔符(莫尔编码). 另一种解决方式是设计编码方式,是得其中每个字符的完整编码都不是另一个字符编码的开始一段.这中编码方式称为前缀编码.一般而言能够通过变长前缀码去利用编码消息中符号出现的相对频度,就能节省空间.完成这一特定时间的方式称为Huffman编码.一个Huffman编码可以表示为一个二叉树,其中的树叶是被编码的符号.树中的每个每个非叶子节点代表一个集合,其中包含饿这一节点之下的所有书上的符号.每个位于书上的符号被赋予一个权重,也就是它的相对频度.非叶子节点所包含的权重位是位于它之下的所有叶子节点的权重之和.这种权重在编码和解码中国并不使用.

下图是一颗Huffman编码树

Huffman 编码树



在用Huffman树做一个序列解码时,我们从树根开始,通过位序列中的0或者1确定是向左移动还是向右移动.每当达到一个叶子节点时就生成出一个符号,然后再从新从树根开始去确定下一个符号,直到解码完给定的的二进制序列为止.

列如,如果有一个序列 .从数根开始,序列的第一位是1, 所以我们向右分支移动,第二位是0,所以我们向左移动,第三位是0 ,所以向左移动.这是已经到达Bde叶,所以被解码消息中的第一个符号是B.接着再从树根开始重复上述过程,最后可以确定整个消息是BAC.



生成Huffman树

给定了符号的 符号表和它们的相对频度,怎么才能构造出最好的编码?(也就是怎样的树能是消息编码的位数最少).Huffman给出了完成这一事件的一个算法,并且证明给了对于符号所出现的相对频度与构造树的消息符号的消息而言,这样产生的编码是最好的边长编码.

生成Huffman树的算法非常简单,就是安排这棵树,使得那些带有最低平度的符号出现在离树根最远的地方.这一构造过程从叶节点的集合开始,这种节点中包含包含各个符号和他们出现的频度,这就是开始构造编码数的初始数据.现在要找出连个具有最低权重的叶,并归并它们,产生出一个以这两个节点为左右分支的节点.新节点的权重就是这两个叶节点的权重之和.然后继续重复这一过程当集合只剩下一个节点时停止,而这个节点就是根节点.



Huffman 编码树

这一算法不总能描述一棵唯一的树,这是因为每步选择出的最小权重节点可能不唯一,在左归并是,两个节点的顺序也是任意的,也就是说,随便哪个都可以作为左分支,或者右分支.

=====================================================

代码来自维基百科

//以下為C++程式碼,在GCC下編譯通過 //僅用於示範如何根據權值構建霍夫曼樹, //沒有經過性能上的優化及加上完善的異常處理。 #include <cstdlib> #include <iostream> #include <deque> #include <algorithm> using namespace std; const int size=10; struct node //霍夫曼樹節點結構 { unsigned key; //保存權值 node* lchild; //左孩子指針 node* rchild; //右孩子指針 }; deque<node*> forest; deque<bool> code; //此處也可使用bitset node* ptr; int frequency[size]={0}; void printCode(deque<bool> ptr); //用於輸出霍夫曼編碼 bool compare( node* a, node* b) { return a->key < b->key; } int main(int argc, char *argv[]) { for(int i=0;i<size;i++) { cin>>frequency[i]; //輸入10個權值 ptr=new node; ptr->key=frequency[i]; ptr->lchild=NULL; ptr->rchild=NULL; forest.push_back(ptr); }//形成森林,森林中的每一棵樹都是一個節點 //從森林構建霍夫曼樹 for(int i=0;i<size-1;i++) { sort(forest.begin(),forest.end(),compare); ptr=new node; //以下代碼使用下標索引隊列元素,具有潛在危險,使用時請注意 ptr->key=forest[0]->key+forest[1]->key; ptr->lchild=forest[0]; ptr->rchild=forest[1]; forest.pop_front(); forest.pop_front(); forest.push_back(ptr); } ptr=forest.front();//ptr是一個指向根的指針 system("PAUSE"); return EXIT_SUCCESS; } void printCode(deque<bool> ptr) { //deque<bool> for (int i=0;i<ptr.size();i++) { if(ptr[i]) cout<<"1"; else cout<<"0"; } }





维基百科连接:http://zh.wikipedia.org/wiki/霍夫曼编码



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232687.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • html一个汉字空格占位_html空格字符

    html一个汉字空格占位_html空格字符1.&nbsp;(常用)不换行空格,全称No-BreakSpace,它是按下space键产生的空格。空格不会累加(只显示一个)。使用html表示才会累加,该空格占据宽度受字体影响。2.&ensp;半角空格,全称EnSpace,en为em宽度的一半(em类似于px受设置不同为20px=1em或其他自定义大小)。占据0.5个中文宽度,不受字体影响。3、&em…

    2022年10月4日
    1
  • 注册邮箱发送短信验证_网易邮箱注册系统未收到短信

    注册邮箱发送短信验证_网易邮箱注册系统未收到短信分享概要:讲述yii框架,用户注册然后以邮箱通知和短信通知用户注册状态。短信使用阿里云,邮箱使用swiftmailer插件。支持php~~~功能点:用户注册通知用户注册类:publicfunctionactionCreateUsers(){//数据过滤数据判断这个省略了。。。。直接看重点if($model->save()){//对用户数据的保存…

    2022年10月13日
    4
  • 子网划分详解与子网划分实例精析

    子网划分详解与子网划分实例精析目录子网划分理论基础为什么进行子网划分明确需求知识点子网划分常见问题子网划分实例精析C类子网划分实例分析已知网络地址和子网掩码,求子网划分结果已知IP地址和子网掩码求子网划分B类地址子网划分实例已知网络地址和子网掩码求子网划分已知ip地址和子网掩码求子网划分A类子网划分实例已知网络地址和子网掩码求子网划分已知ip地址和子网掩码求子网划分小结…

    2022年6月27日
    33
  • h5页面 请在微信客户端打开链接_模拟微信接口时,提示“请在微信客户端打开链接”(转)…[通俗易懂]

    h5页面 请在微信客户端打开链接_模拟微信接口时,提示“请在微信客户端打开链接”(转)…[通俗易懂]背景描述相信有模拟微信页面请求的测试都有看到过这个页面,简单点说就是爬虫爬微信页面,进行回放的时候会出现这个页面。大概在1年前,专门安排了一个人去解决这个技术问题,遗憾的是当时没有找到解决方案,接下来所有微信端的接口测试和性能测试都无法进行,今天和大家分享下我们的解决方案,希望大家可以绕过微信的坑。业务场景我这里以JMeter来举例,我们可以通过在JMeter上开启代理,手机上设置代理来录制微信端…

    2022年6月7日
    32
  • 编程干货│全网最全 adb 命令[通俗易懂]

    编程干货│全网最全 adb 命令[通俗易懂]adb命令是Android开发和测试人员不可替代的强大工具

    2022年7月27日
    7
  • 策略模式+工厂+字典map解决多重if-else

    策略模式+工厂+字典map解决多重if-else

    2021年7月12日
    141

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号