哈夫曼编码C语言
2017-01-01 20:20
337 查看
参考:《软件设计师考试——考点分析与真题详解》
我们设置一个结构数组 huffnode 保存哈夫曼树中各结点的信息。根据二叉树的性质可知,具有n个叶子结点的哈夫曼树共有 2n-1 个结点,所以数组 huffnode 的大小设置为 2n-1 。huffnode 结构中有 weight, lchild, rchild 和 parent 域。其中,weight 域保存结点的权值, lchild 和 rchild 分别保存该结点的左、右孩子的结点在数组 huffnode 中的序号,从而建立起结点之间的关系。为了判定一个结点是否已加入到要建立的哈夫曼树中,可通过
parent 域的值来确定。初始时 parent 的值为 -1。当结点加入到树中去时,该结点 parent 的值为其父结点在数组 huffnode 中的序号,而不会是 -1 了。
求叶结点的编码:
该过程实质上就是在已建立的哈夫曼树中,从叶结点开始,沿结点的双亲链域回退到根结点,每回退一步,就走过了哈夫曼树的一个分支,从而得到一位哈夫曼码值。由于一个字符的哈夫曼编码是从根结点到相应叶结点所经过的路径上各分支所组成的 0、1 序列,因此先得到的分支代码为所求编码的低位,后得到的分支代码为所求编码的高位码。我们可以设置一个结构数组 huffcode 用来存放各字符的哈夫曼编码信息,数组元素的结构中有两个域:bit 和 start。其中,域 bit 为一维数组,用来保存字符的哈夫曼编码, start
表示该编码在数组 bit 中的开始位置。所以,对于第 i 个字符,它的哈夫曼编码存放在 huffcode[i].bit 中的从 huffcode[i].start 到 n 的 bit 位中。
#include<iostream>
#include<cstdio>
using namespace std;
int n;
struct huffnotetype
{
int parent;
int weight;
int lchild;
int rchild;
}huffnote[1005];
struct huffcodetype
{
int start;
int bit[505];
}huffcode[1005],cd;
void buildtree()
{
int i,j;
int m1,m2,x1,x2;
for(i=0;i<n-1;i++)
{
m1=m2=1000000;//找到两个权值最小的并且没被用过的点
x1=x2=0;//存储这俩点下标
for(j=0;j<n+i;j++)
{
if(huffnote[j].weight<m1&&huffnote
4000
[j].parent==-1)//保证这个节点没被用过
{
m2=m1;
x2=x1;
m1=huffnote[j].weight;
x1=j;
}
else if(huffnote[j].weight<m2&&huffnote[j].parent==-1)
{
m2=huffnote[j].weight;
x2=j;
}
}
huffnote[x1].parent=n+i;
huffnote[x2].parent=n+i;
huffnote[n+i].lchild=x1;
huffnote[n+i].rchild=x2;
huffnote[n+i].weight=m1+m2;//建立和两个点的父节点
}
}
void gethuff()//这个部分,读者可以自己建棵哈夫曼树进行模拟一下
{
int i,j,c,p;
for(i=0;i<n;i++)
{
cd.start=n-1;
c=i;
p=huffnote[c].parent;//先从最小的叶子节点开始王根结点找
while(p!=-1)
{
if(huffnote[p].lchild==c)
{
cd.bit[cd.start]=0;
}
else
{
cd.bit[cd.start]=1;
}
c=p;
p=huffnote[c].parent;//循环往复,一直找到根节点
cd.start--;//记录这个节点的编码长度
}
for(j=cd.start+1;j<n;j++)
{
huffcode[i].bit[j]=cd.bit[j];//cd,只是暂时存储,huffcode才是本节点的具体编码信息
}
huffcode[i].start=cd.start+1;
}
}
int main()
{
int i,j;
cin>>n;
for(i=0;i<2*n-1;i++)
{
huffnote[i].weight=0;
huffnote[i].parent=-1;
huffnote[i].lchild=-1;
huffnote[i].rchild=-1;
}//赋初值
for(i=0;i<n;i++)
scanf("%d",&huffnote[i].weight);
buildtree();//建树
gethuff();//得到每个叶子节点的编码值
for(i=0;i<n;i++)
{
printf("%d ",i);
for(j=huffcode[i].start;j<n;j++)
printf("%d",huffcode[i].bit[j]);
printf("\n");
}
}
相关文章推荐
- 简单的四则运算
- 数的奇偶性
- ACMer博客瀑布流分析
- ACM程序设计大赛题目分类
- 2015年acm国内排名
- 计算字符串最后一个单词长度
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- 矩阵的乘法操作
- 蚂蚁爬行问题
- 蚂蚁爬行问题
- 求两个数的最大公约数【ACM基础题】
- 打印出二进制中所有1的位置
- 杭电题目---一只小蜜蜂
- HDOJ 1002 A + B Problem II (Big Numbers Addition)
- 初学ACM - 半数集(Half Set)问题 NOJ 1010 / FOJ 1207
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1002