Huffman编码,
报文中只出现5个字符{A,B,C,D,E} ,他们出现的频次分别为{3,4,5,8,10};
1)给出最经济的编码,
相当于构造一棵叶子带权分别是(3,4,5,8,10)
的最优二叉树(Huffman树)
从树中得到最经济的编码
2)并给出报文的译文长度。
#include <stdio.h>
#include <string.h>
#define N 5
/* Huffman编码,
报文中只出现5个字符{A,B,C,D,E} ,他们出现的频次分别为{3,4,5,8,10};
1)给出最经济的编码,
相当于构造一棵叶子带权分别是(3,4,5,8,10)
的最优二叉树(Huffman树)
从树中得到最经济的编码 ,
2)并给出报文的译文长度。
*/
char zf[]="ABCDE";//字符
int qz[]={3,7,9,5,6};//权值(频率)
char bmb[N][N];//编码表
//赫夫曼树
struct node{
int data;
int l;
int r;
int p;
}arr[N*2-1];
//找到arr数组最小和次小的权值
void select(struct node arr[],int k,int *m1,int *m2){
int i,m11=101,m22=102;
for(i=0;i<k;i++){
if(arr[i].p==-1){
if(arr[i].data<m11){
m22=m11;
m11=arr[i].data;
*m1=i;
}else if(arr[i].data<m22){
m22=arr[i].data;
*m2=i;
}
}
}
}
//构造赫夫曼编码
void huffman(){
int i;
for(i=0;i<N;i++){ //初始化结构体
arr[i].data=qz[i];
arr[i].l=arr[i].r=arr[i].p=-1;
}
for(i=1;i<N;i++){
int m1,m2;
select(arr,N+i,&m1,&m2); //找到最小和次小的权值,为他们生成夫节点
arr[N+i-1].data=arr[m1].data+arr[m2].data;
arr[N+i-1].l=m1;
arr[N+i-1].r=m2;
arr[N+i-1].p=-1;
arr[m1].p=arr[m2].p=N+i-1; //记录父节点序号
}
}
//输出赫夫曼编码
void code(){
int i,j;
for(i=0,j=0;j<N;j++,i=j){
printf("%c的编码:",zf[j]);
int k=0;
while(arr[i].p!=-1){
if(arr[arr[i].p].l==i){
bmb[j][k]='1';
printf("1");
}else{
bmb[j][k]='0';
printf("0");
}
i=arr[i].p;
k++;
}
puts("");
}
}
//输出结构体数据
void print(){
int i;
printf("序号\t父节点\t左孩子\t右孩子\t父节点\n");
for(i=0;i<2*N-1;i++){
printf("%d\t%d\t%d\t%d\t%d\n",i,arr[i].data,arr[i].l,arr[i].r,arr[i].p);
}
puts("");
}
//输出报文的译文长度
int len(){
int lenSum=0;
int i;
for(i=0;i<N;i++){
lenSum+=strlen(bmb[i])*qz[i];
}
return lenSum;
}
int main(){
huffman();//构造赫夫曼编码
print();//输出结构体数据
code();//输出赫夫曼编码
printf("报文的译文长度:%d",len());
return 0;
}
输出结果:
序号 父节点 左孩子 右孩子 父节点
0 3 -1 -1 5
1 7 -1 -1 7
2 9 -1 -1 6
3 5 -1 -1 5
4 6 -1 -1 6
5 8 0 3 7
6 15 4 2 8
7 15 1 5 8
8 30 6 7 -1
A的编码:100
B的编码:10
C的编码:01
D的编码:000
E的编码:11
报文的译文长度:68
--------------------------------
Process exited after 0.01589 seconds with return value 0
请按任意键继续. . .