哈夫曼编码,译码(附带哈夫曼树图形打印)
一道上机作业,那个打印哈夫曼树想了半天程序可能有些漏洞,请高手指点。
(由于打印的原因,程序只能最多处理8个字符的编码,译码)
编译条件(tc2.0)]
#include
#include "stdlib.h"
#include "string.h"
#include
#include
#define PAI 3.1415926
#define MAXVALUE 100 ;/*the max of weight*/
typedef struct
{
int weight;
int parent;
int lchild;
int rchild;
int x;
int y;/* the location of the center of circle*/
}HTNode,*HuffmanTree;
typedef char ** HuffmanCode;
/**************************************************************************/
HuffmanTree CreatHuffman( HuffmanTree HT, int *we, int nChar );
/*put the weight in -we ,creat a Huffman Tree which has -nChar characters*/
void Select(HuffmanTree HT, int *x1, int *x2, int nC,int add );
/*choice two nods whose weight are iower */
void PrintHTree(HuffmanTree HT,int );
/*print Huffman Tree*/
HuffmanCode Code( HuffmanTree HT, int nChar );
/*to code the character base on Huffman Tree*/
void PrintHCode( HuffmanCode HC, int nchar, char* Ch);
/*print the code of the character*/
char* zip(HuffmanCode HC,char *chObj, char* Allchar);
/*code the string of 'chObj' to 's','Allchar' is the all of the characters*/
char* Unzip(HuffmanCode HC, char *chObj, int nchar, char* Allchar);
/*decode the string of 's'*/
void PrintMenu();
void main()
{
int weight[10];
int nCharacter;
int i;
char Characters[9]={'a','b','c','d','e','f','g','h','\0'};/*storage the characters*/
char s1[100]={'\0'};
char s2[100];
char *obj1;
char *obj2;
HuffmanTree HTree;
HuffmanCode HCode;
int choice;
while(1)
{
PrintMenu();
printf("Please enter the choice");
scanf("%d",&choice);
if( choice<1||choice>5 )
{
printf("ERROR,Please reEnter\n");
continue;
}
switch(choice)
{
case 1 :
printf("Please Enter the number of Characters(I am sorry that the max is 8)");
scanf("%d",&nCharacter);
Characters[nCharacter]='\0';
printf( "Please input the weight of the characters:" );
for( i=0; i<NCHARACTER; )
{
printf( "\nPlease input the %d character", i+1 );
scanf( "%d", &weight[i]);
}
printf("NOW Start Coding………………");
HTree=CreatHuffman( HTree, weight, nCharacter );
HCode=Code( HTree, nCharacter );
PrintHTree( HTree, 2*nCharacter-1 );
PrintHCode( HCode, nCharacter, Characters );
break;
case 2 :
printf("Please Enter the strings to be coded\n");
getchar();
gets(s1);
obj1=zip( HCode, s1, Characters );
break;
case 3 :
PrintHCode( HCode, nCharacter, Characters );
printf("Please Enter the strinf to be encoded");
getchar();
gets(s2);
obj2=Unzip( HCode, s2, nCharacter, Characters );
break;
case 4 :
exit(0);
}
}
/* printf( "Please input the weight of the characters:" );
for( i=0; i<NCHARACTER; )
{
printf( "\nPlease input the %d character", i+1 );
scanf( "%d", &weight[i]);
}
obj1=zip( HCode, s1, Characters );
obj2=Unzip( HCode, s2, nCharacter, Characters );*/
}
void PrintMenu()
{
printf(" welcome to the Haffman Coding\n ");
printf(" 1,Creat Huffman Tree\n");
printf(" 2,Coding\n");
printf(" 3,Decoding\n");
printf(" 4,Exit\n");
}
HuffmanCode Code( HuffmanTree HT, int nChar )
/*to code the character base on Huffman Tree*/
{
HuffmanCode HC;
int i;
int tempi;
int start;
int f;
char a='1';
char b='0';
char c='\0';
char* tempcd;/*as the temp of space*/
tempcd = (char *)malloc( nChar * sizeof(char) );
HC = (HuffmanCode)malloc( (nChar+1) * sizeof(char*) );
tempcd[nChar-1] = c;
for( i=0; i<NCHAR; i++)
{
start = nChar-1; /*the location of the flag of the end of the code */
tempi = i;
f = HT[i].parent;
while( f != -1)
{
if(HT[f].lchild == tempi)
tempcd[--start] = b;
else
tempcd[--start] = a;
tempi = f;
f = HT[f].parent;
}
HC[i] = (char*)malloc( (nChar-start) * sizeof(char) );
strcpy( HC[i], &tempcd[start] );
}
free(tempcd);
return HC;
}
char* zip(HuffmanCode HC,char *chObj, char* Allchar)
/*code the string of 'chObj' to 's','Allchar' is the all of the characters*/
{
int j=0;
char p[100][100];
char s1[100];
unsigned int i;
for(i=0; i<STRLEN(CHOBJ);
{
j=0;
while( chObj[i]!=Allchar[j] )
j++;
strcpy(p[i],HC[j]);
}
strcpy(s1,p[0]);
for(i=1; i<STRLEN(CHOBJ)
strcat(s1,p[i]);
puts(s1);
return s1;
}
char* Unzip(HuffmanCode HC,char* s, int nchar, char* Allchar)
/*decode the string of 's'*/
{
int j=0, p=0;
unsigned int i=0;
int k;
int flag=0;
int num=0;
char ch[100];
while( i<STRLEN(S)
{
for( j=0; j<NCHAR; j++)
{
p=i;
k=0;
while( HC[j][k]!='\0')
{
if( s[p] == HC[j][k] )
{
k++;
p++;
}
else
{
flag = 0;
break;
}
if( HC[j][k]=='\0')
flag = 1;
}
if(flag == 1)
break ;
}
if(flag == 1)
{
i=p;
ch[num]=Allchar[j];
num++;
flag = 0;
}
else
{
printf("the code is error!");
break;
}
}
ch[num]='\0';
puts(ch);
return ch;
}
void PrintHCode( HuffmanCode HC, int nchar, char* Ch)
/*print the code of the character*/
{
int i;
for( i=0; i<NCHAR; )
{
printf("\nthe %d charcter is %c ",i,Ch[i] );
puts(HC[i]);
}
}
void Select(HuffmanTree HT, int *x1, int *x2, int nC,int add )
/*Select two the lower weights from HT(nC is the number of
characters, add is added to the times of circle)*/
{
int m1,m2,i;
m1=m2=MAXVALUE;
for( i=0; i<NC+ADD; )
{
/* if( (*(HT+i)->weight)parent==-1 )*/
if( (HT[i].weight)<M1 )
{
m2=m1;
*x2=*x1;
m1=HT[i].weight;
*x1=i;
}
else if( HT[i].weight<M2 )
{
m2=HT[i].weight;
*x2=i;
}
}
}
HuffmanTree CreatHuffman(HuffmanTree HT, int *we, int nChar )
{
int number;/*Storage the H Tree Node*/
int i = 0;
int j;
int *lowerWe1;
int *lowerWe2;
int a=0,b=0;
int rootnum;
/* put the the number of the root in it */
lowerWe1=&a;
lowerWe2=&b;
/*init H tree*/
if( nChar<=-1 )
{
printf("input wrong !\n");
exit(0);
}
number = nChar * 2 - 1;
HT = (HuffmanTree)malloc( (number) * sizeof(HTNode) );
for ( ; i<NUMBER; ++i)
{
HT[i].weight = *(we+i);
HT[i].parent = -1;
HT[i].rchild = -1;
HT[i].lchild = -1;
HT[i].x=0;
HT[i].y=0;
}
for( i=0 ; i<NCHAR-1; )
{
Select( HT, lowerWe1, lowerWe2, nChar, i );
HT[*lowerWe1].parent = nChar+i;
HT[*lowerWe2].parent = nChar+i;
HT[nChar+i].weight = HT[*lowerWe1].weight + HT[*lowerWe2].weight;
HT[nChar+i].lchild = *lowerWe1;
HT[nChar+i].rchild = *lowerWe2;
}
HT[number-1].x=300;
HT[number-1].y=100;
for(j=number-2; j>=0; j--)
{
rootnum = HT[j].parent;
if( HT[rootnum].lchild == j )
/*HT[j].x = HT[rootnum].x-60*sin(PAI/3-rootnum*PAI/10);*/
HT[j].x = HT[rootnum].x-rootnum*rootnum*rootnum/20+15;
else
/*HT[j].x = HT[rootnum].x+60*sin(PAI/3-rootnum*PAI/14);*/
HT[j].x = HT[rootnum].x+rootnum*rootnum*rootnum/20-15;
HT[j].y = HT[rootnum].y+60*cos(PAI/6);
}
return HT;
}
void PrintHTree( HuffmanTree HT, int num )
{
int i;
int gdriver, gmode;
char s[30];
printf("\nnumber root weight lchild rchild x y\n");
for( i=0; i<NUM; i++)
{
printf("%d %d %d %d %d %d %d",i,HT[i].parent,HT[i].weight,HT[i].lchild,HT[i].rchild,HT[i].x,HT[i].y);
printf("\n");
}
/*getch();*/
gdriver=DETECT;
initgraph(&gdriver, &gmode, "c:\\tc");
setbkcolor(BLUE);
cleardevice();
setcolor(12);
settextstyle( 3, LEFT_TEXT, 5 );
outtextxy(200, 10,"HaffumanTree");
settextstyle(SMALL_FONT, LEFT_TEXT, 5);
for (i=0; i<NUM; i++)
{
circle(HT[i].x,HT[i].y,8);
getch();
sprintf(s, "%d", HT[i].weight);
outtextxy(HT[i].x, HT[i].y, s);
}
for(i=num-1; i>=(num+1)/2; i--)
{
line(HT[i].x, HT[i].y, HT[ HT[i].lchild ].x, HT[ HT[i].lchild].y );
line(HT[i].x, HT[i].y, HT[ HT[i].rchild ].x, HT[ HT[i].rchild].y );
}
setcolor(15);
getch();
closegraph();
return 0;
}
HUCOV1.rar
(2.96 KB)