设密码电文是由8个字母组成,每个字母在电文中出现的频率分别是7,19,2,6,32,3,21,10写出哈夫曼编码

如题所述

O
/ \
/ \
/ \
/ \
(53) (40)
/ \ / \
/ \ / \
(32) (21) (21) (19)
/ \
/ \
(11) (10)
/ \
(6) (5)
/ \
(3) (2)
生成的赫夫曼树,根据左节点为0 右节点为1,从根到叶子的最短路径 如概率32的那个字符可以用00 概率21的那个01 ,概率19的11,概率3 的那个表示成10011.
还有//------------------头文件-------------------------------
#i nclude<iostream.h>
#i nclude<iomanip.h>
#i nclude<string.h>
#i nclude<ctype.h>
#i nclude<malloc.h>
#i nclude<stdio.h>
#i nclude<process.h>
typedef int TElemType;
int UINT_MAX=32767;
typedef struct
{
unsigned int weight;
unsigned int parent,lchild,rchild;
}HTNode,* HuffmanTree;
typedef char **HuffmanCode;
//-----------采用全局变量-----------------------
HuffmanTree HT;
HuffmanCode HC;
int *w,i,j,n;
char *z;
int flag=0;
//------------------清空键盘缓冲区---------------
//void Clear_Key_Buffer(void)
//{int offset;
//offset=peek(0x40,0x1a);
//pokeb(0x40,0x1c,offset);
//}
// -----------------求赫夫曼编码-----------------------
int min(HuffmanTree t,int i)
{ // 函数void select()调用
int j,flag;
unsigned int k=UINT_MAX; // 取k为不小于可能的值
for(j=1;j<=i;j++)
if(t[j].weight<k&&t[j].parent==0)
k=t[j].weight,flag=j;
t[flag].parent=1;
return flag;
}
//--------------------slect函数----------------------
void select(HuffmanTree t,int i,int &s1,int &s2)
{ // s1为最小的两个值中序号小的那个
int j;
s1=min(t,i);
s2=min(t,i);
if(s1>s2)
{
j=s1;
s1=s2;
s2=j;
}
}
// --------------算法6.12--------------------------
void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n)
{ // w存放n个字符的权值(均>0),构造赫夫曼树HT,并求出n个字符的赫夫曼编码HC
int m,i,s1,s2,start;
unsigned c,f;
HuffmanTree p;
char *cd;
if(n<=1)
return;
m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); // 0号单元未用
for(p=HT+1,i=1;i<=n;++i,++p,++w)
{
(*p).weight=*w;
(*p).parent=0;
(*p).lchild=0;
(*p).rchild=0;
}
for(;i<=m;++i,++p)
(*p).parent=0;
for(i=n+1;i<=m;++i) // 建赫夫曼树
{ // 在HT[1~i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2
select(HT,i-1,s1,s2);
HT[s1].parent=HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
// 从叶子到根逆向求每个字符的赫夫曼编码
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));
// 分配n个字符编码的头指针向量([0]不用)
cd=(char*)malloc(n*sizeof(char)); // 分配求编码的工作空间
cd[n-1]='\0'; // 编码结束符
for(i=1;i<=n;i++)
{ // 逐个字符求赫夫曼编码
start=n-1; // 编码结束符位置
for(c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)
// 从叶子到根逆向求编码
if(HT[f].lchild==c)
cd[--start]='0';
else
cd[--start]='1';
HC[i]=(char*)malloc((n-start)*sizeof(char));
// 为第i个字符编码分配空间
strcpy(HC[i],&cd[start]); // 从cd复制编码(串)到HC
}
free(cd); // 释放工作空间
}
//--------------初始化赫夫曼链表---------------------------------
void init()
{
flag=1;
int num;
int num2;
/*char *num;
num=(char*)malloc(100*sizeof(char));
char *numBuffer;
numBuffer=(char*)malloc(100*sizeof(char));*/
cout<<"下面初始化赫夫曼链表"<<endl<<"请输入权值或字符的个数n(n>1且注意:必须以回车结束):";
/*shoud Clear_Key_Buffer;
gets(numBuffer);
gets(num);*/
cin>>num;
/*while(!(((int)(*num)>48&&(int)(*num)<=57)&&*(num+1)=='\0')&&!(((int)(*num)>48&&(int)(*num)<=57)&&((int)(*(num+1))>48&&(int)(*(num+1))<=57)&&*(num+2)=='\0'))
{
cout<<"bad guy!read and input again"<<endl;
gets(num);
}
if(*(num+1)=='\0')n=(int)(*num)-48;
else n=((int)(*num)-48)*10+(int)(*(num+1))-48;*/
n=num;
w=(int*)malloc(n*sizeof(int));
z=(char*)malloc(n*sizeof(char));
cout<<"\n请依次输入"<<n<<"个字符(字符型)\n注意:必须以回车结束:"<<endl;

//char *base;
char base[2];
//base=(char*)malloc(100*sizeof(char));
for(i=0;i<=n-1;i++)
{
cout<<endl<<"第"<<i+1<<"个字符:";
gets(base);
/*while(*(base+1)!='\0')
{
cout<<"bad guy!read and input again"<<endl;
gets(base);
}*/
*(z+i)=*base;
}
for(i=0;i<=n-1;i++)
{
cout<<setw(6)<<*(z+i);
}
cout<<"\n请依次输入"<<n<<"个权值(\n注意:必须以回车结束):"<<endl;
for(i=0;i<=n-1;i++)
{
cout<<endl<<"第"<<i+1<<"个字符的权值:";
cin>>num2;
*(w+i)=num2;
/*gets(base);
//--------报错重输语句-------------------------------
while(((int)(*base)<=48||(int)(*base)>57))
{
cout<<"bad guy!read and input again"<<endl;
gets(base);
}
while(((int)(*base)>48&&(int)(*base)<=57)&&((int)(*(base+1))<48||(int)(*(base+1))>57)&&*(base+1)!='\0')
{
cout<<"bad guy!read and input again"<<endl;
gets(base);
}
while((((int)(*base)>48&&(int)(*base)<=57)&&((int)(*(base+1))>=48&&(int)(*(base+1))<=57)&&((int)(*(base+2))<48||(int)(*(base+2))>57))&&*(base+2)!='\0')
{
cout<<"bad guy!read and input again"<<endl;
gets(base);
}
while(((int)(*base)>48&&(int)(*b+ase)<=57)&&((int)(*(base+1))>=48&&(int)(*(base+1))<=57)&&((int)(*(base+2))>=48&&(int)(*(base+2))<=57)&&*(base+3)!='\0')
{
cout<<"bad guy!read and input again"<<endl;
gets(base);
}
if(*(base+1)=='\0')*(w+i)=(int)(*base)-48;
else if(*(base+2)=='\0') *(w+i)=((int)(*base)-48)*10+(int)(*(base+1))-48;
else *(w+i)=((int)(*base)-48)*100+((int)(*(base+1))-48)*10+(int)(*(base+2))-48;*/
}
HuffmanCoding(HT,HC,w,n);
//------------------------打印编码-------------------------------------------
cout<<endl<<"字符对应的编码为:"<<endl;
for(i=1;i<=n;i++)
{
//cout<<"字符"<<*(z+i-1)<<"的编码";
puts(HC[i]);。
温馨提示:答案为网友推荐,仅供参考

相关了解……

你可能感兴趣的内容

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 非常风气网