香农、费诺、哈夫曼、循环码编码

香农、费诺、哈夫曼、循环码编码,第1张

//赫夫曼编码程序(严蔚敏数据结构)

#include <iostream>

using namespace std;

typedef struct

{

int weight;

int parent,lchild,rchild;

}HTNode,HuffmanTree;

typedef char HuffmanCode;

typedef char EachHuffcode;

void Select(HuffmanTree HT,int length,int &s1,int &s2)

{

//s1 lowest,s2 lower

unsigned int min = 5000;

HuffmanTree p = HT;

int i;

for(i = 1, ++p; i <= length ; ++i,++p)

{

if(p->weight < min && p->parent == 0)

{

min = p->weight;

s1 = i;

}

}

min = 5000;

p = HT;

//Get the second less weight

for(i = 1, ++p; i <= length ; ++i,++p)

{

if(p->weight < min && p->parent == 0)

{

if( i == s1)//case s1,ignore

continue;

min = p->weight;

s2 = i;

}

}

}

void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC, int w,int n)

{

if(n <= 1)

return;

int m = 2 n - 1;

HT = new HTNode[m + 1];//0 is not used

HuffmanTree p = HT;

int i;

for( i = 1, ++p; i <= n; ++i,++p,++w)

{

p->weight = w;//NOte: never use this p = {w,0,0,0,0},because p has already been declared

p->parent = p->lchild = p->rchild = 0;

}

for(; i <= m; ++i,++p)

p->weight = p->parent = p->lchild = p->rchild = 0;

int s1;

int s2;

for( i = n + 1; i <= m; ++i)

{

Select(HT,i-1,s1,s2);

HT[s1]parent = i ;

HT[s2]parent = i;

HT[i]lchild = s1;

HT[i]rchild = s2;

HT[i]weight = HT[s1]weight + HT[s2]weight;

}

HC = new EachHuffcode[n+1];//0 is not used

char cd = new char[n];

cd[n-1] = '\0';//the end of each char

int start;

for(int i = 1; i <= n ; ++i)

{//get each huff code for h[1] to h[n]

start = n -1;

for(int c = i, int f = HT[i]parent; f != 0; c = f ,f = HT[f]parent)

if(c == HT[f]lchild) cd[--start] = '0';

else cd[--start] = '1';

HC[i] = new char[n - start];//allocate memory for each HT

strcpy(HC[i],&cd[start]);

}

delete []cd;//don't forget release memory

}

int main(int argc, char argv[])

{

HuffmanTree hftree = NULL;

HuffmanCode hfcode = NULL;

int weight[4] = {7,5,2,4};//four node's weight

HuffmanCoding(hftree,hfcode,weight,4);

EachHuffcode p = hfcode;

++p;

for (int i = 0; i < 4; ++i,++p)

{

cout<<p<<endl;//show each huffman code by each line

}

for(int i = 1; i <=4; ++i)

delete hfcode[i];//release memory

delete []hfcode;

delete []hftree;

return 0;

}

#include<stdioh>

#include<stringh>

#include<stdlibh>

#include<ctypeh>

int n;

struct node{

int w;

int flag;

char c;

struct node plink,llink,rlink;

char code[50];

}num[100],root;

FILE fp;

char tmpcode[50];

int t=0;

void main(void)

{

int i;

void settree(void); //建立树

void code(void); //对文件编码

void decode(void); // 译码

void disp(void);

root=(struct node)malloc(sizeof(struct node));

puts("哈夫曼编/译码器演示");

while(1){

start:

puts("1 初始化 2 编码 3 译码 4显示编码表 5 退出");

while(scanf("%d",&i)!=1)

{

while(getchar()!='\n')

continue;

puts("输入错误!");

puts("请重新输入!");

puts("1 初始化 2 编码 3 译码 4显示编码表 5 退出");

}

switch (i)

{

case 1:

settree();

break;

case 2:

code();

break;

case 3:

decode();

break;

case 4:

disp();

break;

case 5:

exit(0);

default:

puts("输入错误!");

puts("请重新输入!");

goto start;

}

}

}

void settree(void)

{

int i,j,k;

struct node p1,p2,tmp,p;

void go(struct node );

void setcode(struct node );//建立每一个字符的编码

void printtree(struct node );

puts("输入字符集的大小:");

scanf("%d",&n);

while(getchar()!='\n')

continue;

for(i=0;i<n;i++)

{

p=(struct node )malloc(sizeof(struct node));

puts("请输入一个字符");

scanf("%c",&p->c);

while(getchar()!='\n')

continue;

puts("请输入该字符的权值:");

scanf("%d",&p->w);

while(getchar()!='\n')

continue;

p->plink=NULL;

p->rlink=NULL;

p->llink=NULL;

num[i]=p;

}

for(i=0;i<n-1;i++) //(递增)排序

{

for(j=i+1;j<n;j++)

{

if(num[i]->w>num[j]->w)

{

tmp=num[i];

num[i]=num[j];

num[j]=tmp;

}

}

}

/开始建立树/

num[n]=NULL; //结束标志

k=n;

while(num[1]!=NULL)

{

p=(struct node )malloc(sizeof(struct node));

p1=num[0];

p2=num[1];

p->llink=p1;

p->rlink=p2;

p->plink=NULL;

p1->plink=p;

p2->plink=p;

p->w=p1->w+p2->w;

for(i=1;i<k;i++)

{

num[i]=num[i+1];

}

k--;

num[0]=p;

for(i=0;i<k-1;i++) //排序

{

for(j=i+1;j<k;j++)

{

if(num[i]->w>num[j]->w)

{

tmp=num[i];

num[i]=num[j];

num[j]=tmp;

}

}

}

}

root=num[0];

/建立完毕/

/写入文件,前序/

if((fp=fopen("c:\\hfmtreewxl","wb"))==NULL)

{

puts("文件打开错误!");

getchar();

exit(0);

}

setcode(root);

go(root);

fclose(fp);

}

void setcode(struct node p)

{

if(p->llink==NULL&&p->rlink==NULL)

{

tmpcode[t]='\0';

strcpy(p->code,tmpcode);

}

else

{

tmpcode[t++]='0';

setcode(p->llink);

t--;

tmpcode[t++]='1';

setcode(p->rlink);

t--;

}

}

void go(struct node p)

{

if(p->llink==NULL&&p->rlink==NULL)

{

fputc('(',fp);

fputc(p->c,fp);

fputs(p->code,fp);

fputc(')',fp);

}

else

{

go(p->llink);

go(p->rlink);

}

}

void code(void)

{

FILE fp1,fp2,fp3;

char ch1,ch2,c;

if((fp1=fopen("c:\\hfmtreewxl","rb"))==NULL)

{

puts("文件打开错误!");

getchar();

exit(0);

}

if((fp2=fopen("c:\\tobetranstxt","wb"))==NULL)

{

puts("文件打开错误!");

getchar();

exit(0);

}

if((fp3=fopen("c:\\codefilewxl","wb"))==NULL)

{

puts("文件打开错误!");

getchar();

exit(0);

}

while((ch1=fgetc(fp2))!=EOF)

{

t=0;

while((ch2=fgetc(fp1))!=EOF)

{

if(ch1==ch2)

{

while((c=fgetc(fp1))!=')')

{

tmpcode[t++]=c;

}

tmpcode[t]='\0';

fputs(tmpcode,fp3);

fputc('@',fp3);

rewind(fp1);

break;

}

}

}

fclose(fp1);

fclose(fp2);

fclose(fp3);

}

void decode(void)

{

FILE fp1,fp2,fp3;

char ch1,ch2,ch3;

char temp_3[20];

char temp_1[20];

int t1,t3;

if((fp1=fopen("c:\\hfmtreewxl","rb"))==NULL)

{

puts("文件打开错误!");

getchar();

exit(0);

}

if((fp2=fopen("c:\\textfiletxt","wb"))==NULL)

{

puts("文件打开错误!");

getchar();

exit(0);

}

if((fp3=fopen("c:\\codefilewxl","rb"))==NULL)

{

puts("文件打开错误!");

getchar();

exit(0);

}

while((ch3=fgetc(fp3))!=EOF)

{

t3=0;

while(ch3!='@')

{

temp_3[t3++]=ch3;

ch3=fgetc(fp3);

}

temp_3[t3]='\0';

while((ch1=fgetc(fp1))!=EOF)

{

if(isalpha(ch1))

{

ch2=ch1;

t1=0;

while((ch1=fgetc(fp1))!=')')

{

temp_1[t1++]=ch1;

}

temp_1[t1]='\0';

if(strcmp(temp_1,temp_3)==0)

{

fputc(ch2,fp2);

rewind(fp1);

break;

}

}

}

}

fclose(fp1);

fclose(fp2);

fclose(fp3);

}

void disp(void)

{

FILE fp1,fp2;

char ch1,ch2;

char tmp[20];

int t;

if((fp1=fopen("c:\\hfmtreewxl","rb"))==NULL)

{

puts("文件打开错误!");

getchar();

exit(0);

}

if((fp2=fopen("c:\\hfmcodetxt","wb"))==NULL)

{

puts("文件打开错误!");

getchar();

exit(0);

}

while((ch1=fgetc(fp1))!=EOF)

{

if(ch1=='(')

{

t=0;

ch1=fgetc(fp1);

ch2=ch1;

while((ch1=fgetc(fp1))!=')')

{

tmp[t++]=ch1;

}

tmp[t]='\0';

printf("%c-----%s\n",ch2,tmp);

fputc(ch2,fp2);

fputc('-',fp2);

fputc('-',fp2);

fputc('-',fp2);

fputs(tmp,fp2);

fputc('\n',fp2);

}

}

fclose(fp1);

fclose(fp2);

}

#ifndef Huffman_Tree_h

#define Huffman_Tree_h

#endif

#include <stdioh>

typedef struct {

unsigned int weight;

unsigned int parent,lchild,rchild;

}HTNode, HuffmanTree; //存储赫夫曼树的结点类型

typedef char HuffmanCode; //用于存储字符集中各个字符相应的赫夫曼编码

void strcpy(char S1,char S2){ //将字符串S2复制到S1

int i = 0;

while( S2[i] != '\0' ){

S1[i] = S2[i];

i++;

}

S1[i] = '\0';

}

void Select(HuffmanTree HT,int t,int &s1,int &s2){ //在HT[1]到HT[t-1]中找出权值最小的两个S1和S2

int i = 1;

s1 = s2 = 0;

HT[0]weight = 65535;

while( i <= t ){ //遍历查找权值最小的结点S1

if( HT[i]parent == 0 && HT[i]weight < HT[s1]weight )

s1 = i;

i++;

}

i = 1;

while( i <= t ){ //遍历查找除S1外权值最小的结点S2

if( i != s1 && HT[i]parent == 0 && HT[i]weight < HT[s2]weight )

s2 = i;

i++;

}

}

int HuffmanCoding( HuffmanTree &HT,HuffmanCode &HC,int w,int n){ //根据各个字符的权值构造赫夫曼树HT,将对应的赫夫曼编码存储在HC中

int s1,s2,m,i,start;

unsigned int c,f;

HTNode p;

char cd;

if( n <= 1 ) return 0;

m = 2 n - 1; //赫夫曼树的总结点树为m

HT = (HuffmanTree)malloc((m + 1) sizeof(HTNode)); //申请存储赫夫曼树的空间

for(p = HT + 1, i = 1; i <= n; ++i, ++p, ++w){ //将各个叶子结点的weight赋以相应的权值,parent,lchild,rchild均赋为0

p->weight = (w+1);

p->parent = p->lchild = p->rchild = 0;

}

for( ; i <= m; ++i, ++p ){ //将各个非叶子结点的weight,parent,lchild,rchild均赋为0

p->weight = p->parent = p->lchild = p->rchild = 0;

}

for( i = n + 1; i <= m; ++i ){ //构造赫夫曼树,给各个非叶子结点赋值

Select(HT, i - 1, s1, s2);

HT[s1]parent = i; 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 )); //申请空间,用于存储指向存储各个字符相应赫夫曼编码的字符数组的指针

cd = (char )malloc(n sizeof(char)); //申请用于求赫夫曼编码

cd[n - 1] = '\0'; //编码结束符

for( i = 1; i <= n; ++i){ //逐个字符求赫夫曼编码

start = n -1; //编码在数组cd[]中的最前位置

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[]数组的start位置到n-1位置复制给HC[i]

}

free(cd); //释放空间

return 1;

}

以上为第一部分

#include <stdioh>

#include <stdlibh>

#include "Huffman_Treeh"

#define Yes 1 //当程序已经调用过初始化赫夫曼树的InitHuff_T()函数,或已从htfTree文件读取过,则将Init_Mode置为Yes,否则为No

#define No 0

void InitHuff_T( HuffmanTree &HT, HuffmanCode &HC, char ch[],int &n ){ //初始化赫夫曼数,要求用户输入字符和相应权值

int i = 1,w[100],tem,j;

char a[20];

FILE save;

printf("请输入编码字符集的大小n:");

scanf("%d",&n); //获取用户输入的字符集个数

while( i <= n ){ //获取用户输入的字符和相应权值,分别存储在ch[]和w[]数组中

printf("请输入第%d个字符和该字符的权值w:",i);

fflush(stdin);

scanf("%c%d",&ch[i],&w[i]);

i++;

}

ch[i] = '\0';

HuffmanCoding(HT,HC,w,n); //根据用户的输入,生成赫夫曼数及各个字符相应的赫夫曼编码,分别存在HT树和HC中

if(( save = fopen("htfTree","w")) == NULL ){ //打开用于存储赫夫曼树的文件

printf("Open file fail\n");

exit(0);

}

tem = n; //接下来的14行是将字符集大小转换成字符形式写入到文件中

j = 0;

while( tem != 0 ){

tem = tem / 10;

j++;

}

tem = n;

a[j] = '\0';

while( tem != 0 ){

a[j - 1] = (char)(tem % 10 + 48);

tem = tem / 10;

j--;

}

fputs(a,save);

printf("%d\n",n); //向屏幕输出字符集大小n

fputc('\n',save);

for( i = 1; i <= n; i++ ){ //分别向文件和屏幕输出各个字符和相应的赫夫曼编码

fputc(ch[i],save); printf("%c\t",ch[i]);

fputc('\t',save);

fputs(HC[i],save); printf("%s\n",HC[i]);

fputc('\n',save);

}

for(i = 1; i <= 2 n - 1; i++ ){ //将赫夫曼树各个结点的parent,lchild,rchild分别写入到文件中

tem = HT[i]parent; //将i结点的parent转换成字符并写入到文件中

if(tem == 0){

fputc(tem + 48,save);

fputc(' ',save);

}

else{

j = 0;

while( tem != 0 ){

tem = tem / 10;

j++;

}

tem = HT[i]parent;

a[j] = '\0';

while( tem != 0 ){

a[j - 1] = (char)(tem % 10 + 48);

tem = tem / 10;

j--;

}

fputs(a,save);

fputc(' ',save);

}

tem = HT[i]lchild; //将i结点的lchild转换成字符并写入到文件中

if(tem == 0){

fputc(tem + 48,save);

fputc(' ',save);

}

else{

j = 0;

while( tem != 0 ){

tem = tem / 10;

j++;

}

tem = HT[i]lchild;

a[j] = '\0';

while( tem != 0 ){

a[j - 1] = (char)(tem % 10 + 48);

tem = tem / 10;

j--;

}

fputs(a,save);

fputc(' ',save);

}

tem = HT[i]rchild; //将i结点的rchild转换成字符并写入到文件中

if(tem == 0){

fputc(tem + 48,save);

fputc('\n',save);

}

else{

j = 0;

while( tem != 0 ){

tem = tem / 10;

j++;

}

tem = HT[i]rchild;

a[j] = '\0';

while( tem != 0 ){

a[j - 1] = (char)(tem % 10 + 48);

tem = tem / 10;

j--;

}

fputs(a,save);

fputc('\n',save);

}

}

fclose(save);

}

void Encoding(HuffmanTree &HT, HuffmanCode &HC, char ch[]){ //根据赫夫曼编码将用户指定的文件中的字符编成相应的编码,并将所得编码存储到用户指定文件

FILE ToBeTran,CodeFile;

char ToBeTran_Name[100],CodeFile_Name[100]; //存储用户指定文件的文件名

int i;

char c;

printf("请输入所要进行编码的文件的文件名:");

scanf("%s",ToBeTran_Name); //获得所要进行编码的文件的文件名

if(( ToBeTran = fopen(ToBeTran_Name,"r")) == NULL ){ //打开文件

printf("Open file fail\n");

exit(0);

}

printf("请输入编码后编码表示的信息所存储到的文件的文件名:");

scanf("%s",CodeFile_Name); //获得编码后编码表示的信息所存储到的文件的文件名

if(( CodeFile = fopen(CodeFile_Name,"w")) == NULL ){ //打开文件

printf("Open file fail\n");

exit(0);

}

c = fgetc(ToBeTran); //从文件读取一个字符

while( c != EOF ){ //对文件中的各个字符进行编码,直至文件结尾

i = 1;

while( c != ch[i] && ch[i] != '\0' ) //在ch[]数组中查找从文件读取的字符

i++;

if(ch[i] == '\0'){ //未找到,c不在ch[]数组中,c无法被识别,程序出错,退出

printf("字符%c无法识别,程序将退出。\n",c);

exit(0);

}

fputs(HC[i],CodeFile); //若找到,则将c相应的赫夫曼编码写入到文件中

printf("%s",HC[i]); //将c相应的赫夫曼编码输出到屏幕

c = fgetc(ToBeTran); //读入文件中的下一个字符

}

printf("\n");

fclose(ToBeTran);

fclose(CodeFile);

}

void Decoding(HuffmanTree HT, char ch[] , int n){ //对指定的存储由赫夫曼编码表示的信息的文件进行译码,翻译成相应的字符表示,并存储到指定文件

int p,i = 1;

char code[1000],c;

char CodeFile_Name[100],TextFile_Name[100]; //存储用户指定文件的文件名

p = 2 n - 1;

FILE CodeFile,TextFile;

printf("请输入所要译的文件名:");

scanf("%s",CodeFile_Name); //获得所要译的文件的文件名

if(( CodeFile = fopen("CodeFile","r")) == NULL ){ //打开文件

printf("Open file fail\n");

exit(0);

}

printf("请输入译后的字符存储到的文件的文件名:");

scanf("%s",TextFile_Name); //获得译后的字符存储到的文件的文件名

if(( TextFile = fopen(TextFile_Name,"w")) == NULL ){ //打开文件

printf("Open file fail\n");

exit(0);

}

c = fgetc(CodeFile);

while( c != EOF ){

code[i] = c;

i++;

c = fgetc(CodeFile);

}

code[i] = '\0'; //从文件读取字符,存储在code[]数组中

i = 1;

while ( code[i] != '\0' && p != 0 ){ //对数组code[]中的赫夫曼编码进行译码

if ( code[i] == '0' )

p=HT[p]lchild; //进入左分支

else

p = HT[p]rchild; //进入右分支

if (!HT[p]lchild&& !HT[p]rchild){ //进入叶子结点

fputc(ch[p], TextFile); //将相应的字符写入到文件中

printf("%c",ch[p]); //将相应的字符输出到屏幕

p = 2 n - 1; //重新从树根出发进行译码

}

i++;

}

printf("\n");

}

void ReadHuff_T( HuffmanTree &HT, HuffmanCode &HC, char ch[], int &n){ //从文件读取赫夫曼树

FILE htfTree;

char c[100],ch1;

int i,j,t;

if(( htfTree = fopen("htfTree","r")) == NULL ){ //打开存有赫夫曼树信息的文件

printf("Open file fail\n");

exit(0);

}

fgets(c,10,htfTree); //获取赫夫曼树叶子结点个数的字符串表示形式

i = 0; //以下6行将字符串形式转换成整数形式

while( c[i] != '\n' )

i++;

n = 0;

for( j = 0; j < i; j++ )

n = 10 n + c[j] - '0'; //求出叶子结点数n

HC = (HuffmanCode)malloc((n + 1) sizeof(char )); //申请HC空间

HT = (HuffmanTree)malloc((2 n) sizeof(HTNode)); //申请赫夫曼树存储空间

i = 1;

while( i <= n ){

ch[i] = fgetc(htfTree); //读取字符集中的一个字符

HC[i] = (char )malloc((10)sizeof(char)); //申请用于存储读取到的字符集中的字符的赫夫曼编码的空间

fgetc(htfTree); //将‘\t’输出

ch1 = fgetc(htfTree); //读取赫夫曼编码,存储在相应的HC[i][]数组里

int j = 0;

while( ch1 != '\n' ){

HC[i][j] = ch1;

j++;

ch1 = fgetc(htfTree);

}

HC[i][j] = '\0';

i++;

}

ch[i] = '\0';

i = 0;

while( i < 2 n - 1 ){ //读取赫夫曼树的各个结点的parent,lchild,rchild并赋值到赫夫曼树HT中

ch1 = fgetc(htfTree); //读取parent的字符串形式,存储在c[]中,并将其转换成整数形式,赋给HT[i]parent

j = 0;

while( ch1 != ' ' ){

c[j] = ch1;

j++;

ch1 = fgetc(htfTree);

}

HT[i+1]parent = 0;

for( t = 0; t < j; t++ )

HT[i+1]parent = 10 HT[i+1]parent + c[t] - '0';

ch1 = fgetc(htfTree); //读取lchild的字符串形式,并将其转换成整数形式,赋给HT[i]lchild

j = 0;

while( ch1 != ' ' ){

c[j] = ch1;

j++;

ch1 = fgetc(htfTree);

}

HT[i+1]lchild = 0;

for( t = 0; t < j; t++ )

HT[i+1]lchild = 10 HT[i+1]lchild + c[t] - '0';

ch1 = fgetc(htfTree); //读取rchild的字符串形式,并将其转换成整数形式,赋给HT[i]rchild

j = 0;

while( ch1 != '\n' ){

c[j] = ch1;

j++;

ch1 = fgetc(htfTree);

}

HT[i+1]rchild = 0;

for( t = 0; t < j; t++ )

HT[i+1]rchild = 10 HT[i+1]rchild + c[t] - '0';

i++;

}

}

int main(){

HuffmanTree HT;

HuffmanCode HC;

char ch[100]; //用于存储字符集

int n,Init_Mode = No; //n为字符集的大小,Init_Mode = No 表示内存中没有赫夫曼树的信息

char mode; //让用户选择不同的 *** 作

printf("请输入你要选择的功能\n");

printf("\t\tI -- 初始化\t\tE -- 编码\n");

printf("\t\tD -- 译码 \t\tQ -- 退出程序\n");

scanf("%c",&mode); //获得用户选择的 *** 作

while( mode != 'Q' && mode != 'q' ){ //当用户输入不为Q或q时,执行相应 *** 作

switch(mode){

case 'I' :

InitHuff_T(HT,HC,ch,n);

Init_Mode = Yes;

break;

case 'i' :

InitHuff_T(HT,HC,ch,n);

Init_Mode = Yes;

break;

case 'E' :

if( No == Init_Mode )

ReadHuff_T(HT,HC,ch,n);

Encoding(HT,HC,ch);

Init_Mode = Yes;

break;

case 'e' :

if( No == Init_Mode )

ReadHuff_T(HT,HC,ch,n);

Encoding(HT,HC,ch);

Init_Mode = Yes;

break;

case 'D' :

if( No == Init_Mode )

ReadHuff_T(HT,HC,ch,n);

Decoding(HT,ch,n);

Init_Mode = Yes;

break;

case 'd' :

if( No == Init_Mode )

ReadHuff_T(HT,HC,ch,n);

Decoding(HT,ch,n);

Init_Mode = Yes;

default :

printf("您的输入有错,请重新选择\n");

}

printf("请输入你要选择的功能\n");

printf("\tI -- 初始化\tE -- 编码\n");

printf("\tD -- 译码 \tQ -- 退出程序\n");

fflush(stdin);

scanf("%c",&mode); //让用户继续选择相应的 *** 作,直至用户选择退出

}

return 0;

}

第二部分

1。进vc++60

2。新建一个新工程 选择Win32 Console application

一个空工程 确认

3。新建一个c++源文件 命名为Huffman_Treeh 记住 命名很重要 然后将第一部分烤贝 粘贴 一定得是这个名字 然后编译保存

4。在新建一个c++源文件命名为 赫夫曼cpp 然后将第二部分拷贝 粘贴 编译保存 然后就大功告成了 可以执行了

需要注意的是 编译后生成的可执行文件保存在 你新建工程是的那个默认文件夹里 当然你也可以在新建工程是选择你想要保存可执行文件的文件夹 方便查找

哈夫曼在上世纪五十年代初就提出这种编码时,根据字符出现的概率来构造平均长度最短的编码。它是一种变长的编码。在编码中,若各码字长度严格按照码字所对应符号出现概率的大小的逆序排列,则编码的平均长度是最小的。(注:码字即为符号经哈夫曼编码后得到的编码,其长度是因符号出现的概率而不同,所以说哈夫曼编码是变长的编码。) 而且哈夫曼编码是按照子树到父亲,而其读码则是完全相反的。 因此,后来有人提出了一种动态的哈夫曼编码方法。动态哈夫曼编码使用一棵动态变化的哈夫曼树,对第t+1个字符的编码是根据原始数据中前t个字符得到的哈夫曼树来进行的,编码和解码使用相同的初始哈夫曼树,每处理完一个字符,编码和解码使用相同的方法修改哈夫曼树,所以没有必要为解码而保存哈夫曼树的信息。编码和解码一个字符所需的时间与该字符的编码长度成正比,所以动态哈夫曼编码可实时进行。动态哈夫曼编码比静态哈夫曼编码复杂的多,有兴趣的读者可参考有关数据结构与算法的书籍。

前面提到的JPEG中用到了哈夫曼编码,并不是说JPEG就只用哈夫曼编码就可以了,而是一幅经过多个步骤后得到它的一列数值,对这些数值进行哈夫曼编码,以便存储或传输。哈夫曼编码方法比较易懂,大家可以根据它的编码方法,自己编写哈夫曼编码和解码的程序。

哈夫曼树的构造算法。

const maxvalue= 10000; {定义最大权值}

maxleat=30; {定义哈夫曼树中叶子结点个数}

maxnode=maxleaf2-1;

type HnodeType=record

weight: integer;

parent: integer;

lchild: integer;

rchild: integer;

end;

HuffArr:array[0maxnode] of HnodeType;

var ……

procedure CreatHaffmanTree(var HuffNode: HuffArr); {哈夫曼树的构造算法}

var i,j,m1,m2,x1,x2,n: integer;

begin

readln(n); {输入叶子结点个数}

for i:=0 to 2n-1 do {数组HuffNode[ ]初始化}

begin

HuffNodeweight=0;

HuffNodeparent=-1;

HuffNodelchild=-1;

HuffNoderchild=-1;

end;

for i:=0 to n-1 do read(HuffNodeweight); {输入n个叶子结点的权值}

for i:=0 to n-1 do {构造哈夫曼树}

begin

m1:=MAXVALUE; m2:=MAXVALUE;

x1:=0; x2:=0;

for j:=0 to n+i-1 do

if (HuffNode[j]weight<m1) and (HuffNode[j]parent=-1) then

begin m2:=m1; x2:=x1;

m1:=HuffNode[j]weight; x1:=j;

end

else if (HuffNode[j]weight<m2) and (HuffNode[j]parent=-1) then

begin m2:=HuffNode[j]weight; x2:=j; end;

{将找出的两棵子树合并为一棵子树}

HuffNode[x1]parent:=n+i; HuffNode[x2]parent:=n+i;

HuffNode[n+i]weight:= HuffNode[x1]weight+HuffNode[x2]weight;

HuffNode[n+i]lchild:=x1; HuffNode[n+i]rchild:=x2;

end;

end;

呵呵,分数太少了啊。代码贴给你了,测试没问题#include "stdafxh"

// Huffmancpp : 定义控制台应用程序的入口点。

//

#include <stdioh>

#include <stringh>

#define N 50 /叶子结点数/

#define M 2N-1 /树中结点总数/typedef struct

{

char data[5]; /结点值/

int weight; /权重/

int parent; /双亲结点/

int lchild; /左孩子结点/

int rchild; /右孩子结点/

} HTNode;typedef struct

{

char cd[N]; /存放哈夫曼码/

int start;

} HCode;void CreateHT(HTNode ht[],int n)

{

int i,k,lnode,rnode;

int min1,min2;

for (i=0;i<2n-1;i++) /所有结点的相关域置初值-1/

ht[i]parent=ht[i]lchild=ht[i]rchild=-1;

for (i=n;i<2n-1;i++) /构造哈夫曼树/

{

min1=min2=32767; /lnode和rnode为最小权重的两个结点位置/

lnode=rnode=-1;

for (k=0;k<=i-1;k++)

if (ht[k]parent==-1) /只在尚未构造二叉树的结点中查找/

{

if (ht[k]weight<min1)

{

min2=min1;rnode=lnode;

min1=ht[k]weight;lnode=k;

}

else if (ht[k]weight<min2)

{

min2=ht[k]weight;rnode=k;

}

}

ht[lnode]parent=i;ht[rnode]parent=i;

ht[i]weight=ht[lnode]weight+ht[rnode]weight;

ht[i]lchild=lnode;ht[i]rchild=rnode;

}

}void CreateHCode(HTNode ht[],HCode hcd[],int n)

{

int i,f,c;

HCode hc;

for (i=0;i<n;i++) /根据哈夫曼树求哈夫曼编码/

{

hcstart=n;c=i;

f=ht[i]parent;

while (f!=-1) /循序直到树根结点/

{

if (ht[f]lchild==c) /处理左孩子结点/

hccd[hcstart--]='0';

else /处理右孩子结点/

hccd[hcstart--]='1';

c=f;f=ht[f]parent;

}

hcstart++; /start指向哈夫曼编码最开始字符/

hcd[i]=hc;

}

}void DispHCode(HTNode ht[],HCode hcd[],int n)

{

int i,k;

int sum=0,m=0,j;

printf(" 输出哈夫曼编码:\n"); /输出哈夫曼编码/

for (i=0;i<n;i++)

{

j=0;

printf(" %s:\t",ht[i]data);

for (k=hcd[i]start;k<=n;k++)

{

printf("%c",hcd[i]cd[k]);

j++;

}

m+=ht[i]weight;

sum+=ht[i]weightj;

printf("\n");

}

printf("\n 平均长度=%g\n",10sum/m);

}

void main()

{

int i, n=4;

char str[]={"A","B","C","D"};

int fnum[]={1,3,4,7}; HTNode ht[M];

HCode hcd[N];

for (i=0; i<n; i++)

{

strcpy(ht[i]data, str[i]);

ht[i]weight=fnum[i];

}

printf("\n");

CreateHT(ht,n);

CreateHCode(ht,hcd,n);

DispHCode(ht,hcd,n);

printf("\n");

system("pause");

}

以上就是关于香农、费诺、哈夫曼、循环码编码全部的内容,包括:香农、费诺、哈夫曼、循环码编码、哈夫曼编码问题,高手帮我、求数据结构哈夫曼编码译码器等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zz/10176582.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-06
下一篇2023-05-06

发表评论

登录后才能评论

评论列表(0条)

    保存