回 帖 发 新 帖 刷新版面

主题:求解 哈夫曼编码

题一  哈夫曼编码

问题描述
某情报部门经常用计算机网络传递情报,为了又快又安全地传递,就需要对情报中用到的专用术语进行压缩和编码。已知N种术语S1,S2,......,Sn的使用频率分别为P1,P2,......,Pn,现要求用0,1串对它们进行编码,其编码规则如下:

采取不定长的编码方式。(1)为了便于译码,要求任一种术语的编码都不能是其它术语编码的前缀;(2)使用频率高的术语,其编码长度应该最短,也就是说:若术语Si的编码Ci的长度为Li,则你的编码方案应使

WPL=P1*L1+P2*L2+......+Pn*Ln

的值最小。

【输入格式】

输入为n+1行    

第1行:一个整数n()1<=n<=100;为术语的个数;
第2--n+1行:Si Pi;Si为字符串,表示术语;Pi表示使用频率

【输出格式】

输出为n+1行

第1--n行:Si Pi Ci,Ci为Si的编码
第n+1行:一个整数,最小的WPL值。

【输入输出样例】

输入文件名:tree7.in

4
brain 4
work 2
gun 11
money 3 

输出文件名:tree7.out

brain 4 10 
work 2 110 
gun 11 0 
money 3 111 

33 

回复列表 (共3个回复)

沙发

建议先认真了解一下Huffman Tree:

建立哈夫曼树
[算法描述]
1.将给定的n个结点构成n棵二叉树的集合F={T1,T2,T3,...,Tn}.其中每棵二叉树Ti中只有一个权值为wi的根结点ki,其左右子树均为空;
2.在F中选取根结点最小的两棵二叉数作为左右子树,构造一棵新的二叉树,并且置新的二叉树的根结点的权值为其左右子树根结点的权值之和;
3.在F中删除这两棵二叉树,同时将新得到的二叉数加入F中;
4.重复2,3,直到F中只含有一棵二叉树为止.
这棵二叉树就是哈夫曼树.
[源程序]
procedure huffman(var tree:treetype; var root:integer; w:rectype; n:integer);
var
  i,count:integer;
begin
  for i:=1 to n do
  begin
    tree[i].data:=w[i].data;
    tree[i].lch:=0;
    tree[i].rch:=0;
    w[i].addr:=i;
  end;
  root:=n;
  count:=n;
  while count>1 do
  begin
    sort(w,count); //对w的前count个元素按data域升序排序
    root:=root+1;
    tree[root].data:=w[1].data+w[2].data;
    tree[root].lch:=w[1].addr;
    tree[root].rch:=w[2].addr;
    w[1].data:=tree[root].data;
    w[1].addr:=root;
    w[2]:=w[count];
    count:=count-1;
  end;
end;


集合F中每棵二叉树根结点的权值就是每个术语的使用频率,建立好Huffman Tree后,对其进行一次先序遍历就能得出每个术语的Huffman编码了。

板凳

谢谢游侠UFO

3 楼

#define INT_MAX 10000 
#define ENCODING_LENGTH 1000 
#include "stdio.h" 
#include "string.h" 
#include "malloc.h" 
typedef enum{none,left_child,right_child} Which;//标记是左孩子还是右孩子 
typedef char Elemtype; 
typedef struct TNode{ 
Elemtype letter; 
int weight; 
int parent; 
Which sigh; 
char *code; 
}HTNode,*HuffmanTree; 
int n; 
char coding[50];//储存代码 
char str[ENCODING_LENGTH];//保存要翻译的句子 
void InitTreeNode(HuffmanTree &HT){//初始前N个结点,后M-N个结点置空 
int i;int w;char c; 
int m=2*n-1; 
HuffmanTree p; 
HT=(HuffmanTree)malloc((m)*sizeof(HTNode)); 
printf("input %d database letter and weight",n); 
p=HT; 
getchar(); 
for (i=1;i<=n;i++){ 
scanf("%c%d",&c,&w); 
p->code='\0'; 
p->letter=c; 
p->parent=0; 
p->sigh=none; 
p->weight=w; 
p++; 
getchar(); 

for (;i<=m;i++,p++){ 
p->code='\0'; 
p->letter=' '; 
p->parent=0; 
p->sigh=none; 
p->weight=0; 

}//INITTREENODE 
void Select(HuffmanTree HT,int end,int *s1,int *s2){//在0~END之间,找出最小和次小的两个结点序号,返回S1,S2 
int i; 
int min1=INT_MAX; 
int min2; 
for (i=0;i<=end;i++){//找最小的结点序号 
if (HT[i].parent==0&&HT[i].weight<min1){ 
*s1=i; 
min1=HT[i].weight; 


min2=INT_MAX; 
for(i=0;i<=end;i++){//找次小结点的序号 
if (HT[i].parent==0&&(*s1!=i)&&min2>HT[i].weight){ 
*s2=i; 
min2=HT[i].weight; 



void HuffmanTreeCreat(HuffmanTree &HT){//建立HUFFMAN树 
int i;int m=2*n-1; 
int s1,s2; 
for(i=n;i<m;i++){ 
Select(HT,i-1,&s1,&s2); 
HT[s1].parent=i; 
HT[s2].parent=i; 
HT[s1].sigh=left_child; 
HT[s2].sigh=right_child; 
HT[i].weight=HT[s1].weight+HT[s2].weight; 



void HuffmanTreeCode(HuffmanTree HT){//HUFFMAN译码 
int i; 
char *temp; 
temp=(char *)malloc(n*sizeof(char)); 
temp[n-1]='\0'; 
int p;int s; 
for (i=0;i<n;i++){ 
p=i; 
s=n-1; 
while (HT[p].parent!=0){//从结点回溯,左孩子为0,右孩子为1 
if (HT[p].sigh==left_child) 
temp[--s]='0'; 
else if (HT[p].sigh==right_child) 
temp[--s]='1'; 
p=HT[p].parent; 

HT[i].code=(char *)malloc((n-s)*sizeof(char));//分配结点码长度的内存空间 
strcpy(HT[i].code,temp+s); 
printf("%s\n",HT[i].code); 


void GetCodingSen(char *sencence){//输入要编码的句子 
int l; 
gets(sencence); 
l=strlen(sencence); 
sencence[l]='\0'; 

void HuffmanTreeEncoding(char sen[],HuffmanTree HT){//将句子进行编码 
int i=0;int j; 
while(sen[i]!='\0'){ 
for(j=0;j<n;j++){ 
if (HT[j].letter==sen[i]) //字母吻合则用代码取代 
{strcat(coding,HT[j].code); 
break; 


i++; 
if (sen[i]==32) i++; 

printf("\n%s",coding); 

void HuffmanTreeDecoding(HuffmanTree HT,char code[]){//HUFFMAN译码过程,将代码翻译为句子 
char sen[100]; 
char temp[50]; 
char voidstr[]=" "; 
int i;int j; 
int t=0;int s=0; 
for(i=0;i<strlen(code);i++){ 
temp[t++]=code[i]; 
for(j=0;j<n;j++){ 
if (strcmp(HT[j].code,temp)==0){//代码段吻合 
sen[s]=HT[j].letter;s++; 
strcpy(temp,voidstr);//将TEMP置空 
t=0; 
break; 



printf("\n%s",sen); 


void main(){ 
HTNode hnode; 
HuffmanTree huff; 
huff=&hnode; 
printf("input the letter for coding number\n"); 
scanf("%d",&n); 
InitTreeNode(huff); 
HuffmanTreeCreat(huff); 
HuffmanTreeCode(huff); 
GetCodingSen(str); 
HuffmanTreeEncoding(str,huff); 
HuffmanTreeDecoding(huff,coding); 
}

我来回复

您尚未登录,请登录后再回复。点此登录或注册