HuffmanTree的实现及Huffman编码
来源:互联网 发布:apache tomcat什么意思 编辑:程序博客网 时间:2024/05/16 08:08
HuffTree的定义:
假设一共有n个data,第i个data有对应的权值wi。使从根节点到所有data的路径长度乘以其权值和为最小。符合其条件的树就是HuffmanTree,也被称为最优二叉树。
实现步骤:
- 先将n个data建成n个只有一个根节点的数
- 然后从n个中找出两个最小的data
- 将这两个数合并为一个二叉树,左孩子为最小值,右孩子为第二小值
- 将这个树的根节点的权值设为原来两个点的权值之和
- 在剩下的n-1个根节点中执行步骤2
- 直到只剩下一个根节点,结束循环。
下面来讲一下HuffmanTree的一个最经典的应用,Huffman编码。
(以下定义摘自百度百科)
Huffman编码是一种无前缀变字长编码。解码时不会混淆。
使用Huffman编码的前提是知道每一个字母出现的频率。
在编码时,字母出现的频率相当于HuffmanTree中的data的权值。然后从根节点开始,每经过一个左子树,编码加一个0。每经过一个右子树,编码加一个1。
这样建树之后,每一个字母都有自己的唯一编码,且无重复前缀。
HuffmanTree及编码的实现代码:
#include<iostream>#include<cstdlib>#include<cstring>#include<cstdio>using namespace std;const int maxn=100;typedef struct { int weight; int parent,lchild,rchild;}HafNode;//HuffmanTree的基本定义typedef struct { int weight; char data; char code[maxn];//需要被建树的信息}HafCode;void Init(HafCode *h,int &n)//初始化输入数据{ cout<<"Input The Number"<<endl; cin>>n; cout<<"Input The Character And Weight"<<endl; for(int i=0;i<n;++i) cin>>h[i].data>>h[i].weight;}void select(HafNode *h,int k,int &s1,int &s2)//选择两个最小的值{ int i; for(i=0; i<k && h[i].parent != 0; ++i);//选择一个父节点为0的根节点 s1 = i; for(i=0; i<k; ++i){ if(h[i].parent==0 && h[i].weight<h[s1].weight) s1 = i; } for(i=0; i<k; ++i){ if(h[i].parent==0 && i!=s1) break; } s2 = i; for(i=0; i<k; ++i){ if(h[i].parent==0 && i!=s1 && h[i].weight<h[s2].weight) s2 = i; }}void Huffman(HafCode *h2,HafNode *h1,int n){ char str[maxn]; int m=2*n-1; for(int i=0;i<m;++i){ if(i<n)//前n个全部是叶子节点, h1[i].weight=h2[i].weight; else//后面的是还没建成的树 h1[i].weight==0; h1[i].lchild=h1[i].parent=h1[i].rchild=0; } int s1,s2; for(int i=n;i<m;++i){ select(h1,i,s1,s2); h1[s1].parent=i;//建立二叉树 h1[s2].parent=i; h1[i].lchild=s1; h1[i].rchild=s2; h1[i].weight=h1[s1].weight+h1[s2].weight; //cout<<h1[s1].weight<<" "<<h1[s2].weight<<endl; } str[n]='\0'; //memset(str,0,sizeof(str)); int l,p; for(int i=0;i<n;++i){//从每个叶子节点开始倒序遍历 l=n-1;//倒序赋值字符串 //cout<<h2[i].data<<endl; for(int k=i,p=h1[k].parent;p;k=p,p=h1[k].parent){//沿着叶子回溯到根节点 if(k==h1[p].lchild) str[l]='0'; else str[l]='1'; // cout<<str[l]; l--; } //cout<<endl; strcpy(h2[i].code,str+l+1); }}int main(){ int n; HafCode hc[maxn]; HafNode tree[maxn]; Init(hc,n); Huffman(hc,tree,n); for(int i=0;i<n;++i) cout<<hc[i].data<<" "<<hc[i].code<<endl; return 0;}
0 0
- HuffmanTree的实现及Huffman编码
- Huffman树及编码的实现
- Huffman编码的实现
- Huffman编码的实现
- Huffman编码的实现
- huffman编码及解码实现
- Huffman编码用MTLAB的实现及编码注释----------Matlab
- HuffmanTree的实现
- C++Huffman树的构造实现及编码译码过程
- 范式Huffman编码的实现
- Huffman树及编码C++实现
- HuffmanTree建立、输出、编码及解码
- huffman树的编码及应用
- 树的应用及Huffman编码
- Huffman树的创建及编码
- Huffman树的构造及编码
- Huffman编码的8种实现方式
- Huffman编码的8种实现方式
- POJ 2406 Power Strings <后缀数组(DC3) / KMP>
- mysql-5.7.18-winx64 免安装配置
- 单页SEO
- numpy的基本用法(二)——基本运算
- 求平面最近点对 二分法
- HuffmanTree的实现及Huffman编码
- linux中强大且常用命令:find、grep
- CEF简介
- path与publicPath的区别
- 如何在Linux中装QT(ubuntu)
- Mongdb基本操作
- java集合类原理分析
- 水波特效c#实现
- 每天一个linux命令(43):killall命令