Huffman树及其应用
2015-08-19 15:04
447 查看
哈夫曼树又称为最优二叉树,哈夫曼树的一个最主要的应用就是哈夫曼编码,本文通过简单的问题举例阐释哈夫曼编码的由来,并用哈夫曼树的方法构造哈夫曼编码,最终解决问题来更好的认识哈夫曼树的应用--哈夫曼编码。
那么用二叉树表示为:
HuffmanTest
一、引子
在学习中我们经常遇到将各科成绩改为优秀、良好、中等、及格和不及格。那么根据分级原理,代码表示为:if(a<60) b="不及格“; elseif(a<70) b="及格"; elseif(a<80) b="中等"; elseif(a<90) b="良好"; elseif(a<70) b="优秀";
那么用二叉树表示为:
#include<iostream>
#include<stdio.h>
usingnamespacestd;
constintMAXBIT=100;
constintMAXVALUE=1000;
//创建结构体,抽象描述树节点
typedefstructHuffmanNode
{
intparent;
intlchild;
intrchild;
//结点权重
intweight;
//可以写字母等其他雷兴国
intvalue;
}stu_HuffmanNode,*pHuffmanNode;
//创建结构体,保存编码
typedefstructHuffmanCode
{
//编码的bit
intBit[MAXBIT];
intstart;
}*pHuffmanCode;
//在Huffman结点数组中找权值最小的两个结点i1和i2
voidSelectNode(pHuffmanNodeitemnode,int&MinNum1,int&MinNum2,intnum)
{
/*假设两个结点的权值*/
intMaxWeight1,MaxWeight2;
MaxWeight1=MaxWeight2=10000;
/*找出所有结点中权值最小、无父结点的两个结点*/
for(inti=0;i<num;i++)
{
//parent不为-1,就是已经判断过了。
if(itemnode[i].weight<MaxWeight1&&itemnode[i].parent==-1)
{
//将m1赋值给m2保证m1是最小的,m2是第二小的
MaxWeight2=MaxWeight1;
MinNum2=MinNum1;
MaxWeight1=itemnode[i].weight;
MinNum1=i;
}
elseif(itemnode[i].weight<MaxWeight2&&itemnode[i].parent==-1)
{
MaxWeight2=itemnode[i].weight;
MinNum2=i;
}
}
}
//创建huffman树
voidCreateHuffman(pHuffmanNodeHuffmanNodeArray,intn)
{
//创建树结点
//叶子结点(度为0)的个数为n,分支结点(度为2的n2)是n-1,二叉树没有n1,所以树结点为2*n-1;
for(inti=0;i<2*n-1;i++)
{
HuffmanNodeArray[i].weight=0;
HuffmanNodeArray[i].parent=-1;
HuffmanNodeArray[i].lchild=-1;
HuffmanNodeArray[i].rchild=-1;
HuffmanNodeArray[i].value=i;
}
//创建权值的结点,也就是在HUffman中叶子结点
for(inti=0;i<n;i++)
{
cout<<"Pleaseinputweightofleafnode"<<endl;
cin>>HuffmanNodeArray[i].weight;
}
//循环构建Huffman树,需要判断n-1次
for(inti=n;i<2*n-1;i++)
{
intminNum1=0;
intminNum2=0;
SelectNode(HuffmanNodeArray,minNum1,minNum2,i);
//minNum1,minNum2数值小于n,其实就是为叶子结点确定父节点是谁。
HuffmanNodeArray[minNum1].parent=i;
HuffmanNodeArray[minNum2].parent=i;
//创建两个叶子结点的父节点(分支结点),确定左右孩子,赋值权重
HuffmanNodeArray[i].weight=HuffmanNodeArray[minNum1].weight+HuffmanNodeArray[minNum2].weight;
HuffmanNodeArray[i].rchild=minNum1;
HuffmanNodeArray[i].lchild=minNum2;
}
}
voidCreateHuffmanCode(pHuffmanNodeitemHuffmanNode,pHuffmanCodeitemHuffmanCode,intn)
{
//获取huffman树,从叶子结点开始遍历,现找到叶子结点的父节点,如果此节点在左边就是0,否则就是1
intntemp,ptemp;
HuffmanCodephutemp;
for(inti=0;i<n;i++)
{
ntemp=i;
phutemp.start=n-1;
ptemp=itemHuffmanNode[i].parent;
//循环这个叶子结点的父节点,当父节点为-1是,就是到了树的根节点
while(ptemp!=-1)
{
if(itemHuffmanNode[ptemp].lchild==ntemp)
{
phutemp.Bit[phutemp.start]=0;
}
else
phutemp.Bit[phutemp.start]=1;
phutemp.start--;
ntemp=ptemp;
ptemp=itemHuffmanNode[ntemp].parent;
}
/*保存求出的每个叶结点的哈夫曼编码和编码的起始位*/
for(intj=phutemp.start+1;j<n;j++)
{itemHuffmanCode[i].Bit[j]=phutemp.Bit[j];}
itemHuffmanCode[i].start=phutemp.start;
}
}
//解码
voiddecodeHuffman(char*str,pHuffmanNodeitemHuffmanNode,intNum)
{
inti,tmp=0,code[1024];
intm=2*Num-1;
char*nump;
charnum[1024];
//将权值设置为0,1
for(i=0;i<strlen(str);i++)
{
if(str[i]=='0')
num[i]=0;
else
num[i]=1;
}
i=0;
nump=&num[0];
while(nump<(&num[strlen(str)]))
{
tmp=m-1;
//循环获取叶子结点在数组中序号
while(itemHuffmanNode[tmp].lchild!=-1&&itemHuffmanNode[tmp].rchild!=-1)
{
if(*nump==0)
{
tmp=itemHuffmanNode[tmp].lchild;
}
else
tmp=itemHuffmanNode[tmp].rchild;
nump++;
}
}
cout<<itemHuffmanNode[tmp].value<<endl;
}
intmain()
{
HuffmanNodeHuffmanNodeArray[100];
HuffmanCodeHuffmanCodeArray[100];
pHuffmanNodephuffman=&HuffmanNodeArray[0];
pHuffmanCodephuffmancode=&HuffmanCodeArray[0];
cout<<"输入个数"<<endl;
intn;
cin>>n;
CreateHuffman(phuffman,n);
CreateHuffmanCode(phuffman,phuffmancode,n);
for(inti=0;i<n;i++)
{
cout<<phuffmancode[i].start<<endl;
}
cout<<"输入解码符号"<<endl;
inttest;
cin>>test;
decodeHuffman("test",phuffman,n);
system("pause");
}
HuffmanTest
相关文章推荐
- 电脑经验--bois用pe进不去,更改UEFI
- 纯fragment布局实现tab
- Antenna Placement(POJ_3020)
- java序列化的机制和原理
- Java中super的使用
- 电脑经验--20140325 jre 考勤无法登陆
- PopupWindow
- AngularJS 从入门到精通(过滤器(Filter) )
- HDU 1814 Peaceful Commission (2-SAT)
- House Robber II
- Nginx发布1.9.0版本,新增支持TCP代理和负载均衡的stream模块
- Communication System(dp)
- openwrt su : must be suid to work properly
- Azure REST API (2) Azure Storage
- 装 MSDE2000 后,1433 端口未监听的问题[整理转贴]
- 升级版控制台神兽
- hdu2018 dp
- Communication System(dp)
- android 第三方 Im
- 输入日期及提醒事件并输出