哈夫曼/霍夫曼/赫夫曼编码

适这学期学数据结构,刚刚学了树和二叉树。遂写了哈夫曼编码作业。当然其中还有一部分不是太完善,在这里也就不注释了。

注意:本文的程序是在VS2005下编译的,试过在VC++6下会有错,那是字符串的初始化后不自动为空所产生问题。

下面给出这几个文件

 head.h文件操作的函数:

 

#include  < stdio.h >
#include 
< stdlib.h >
#include 
< conio.h >  
#include 
" stack.h "
#include 
" hfm.h "
// #include"hfm1.h"
void  writefile( char   * s, char   * fn){
    FILE 
* fp ;
    
int  i = 0 ;
    fp
= fopen(fn, " w " );
    
while  (s[i]) {
      fputc(s[i], fp); 
      i
++
     }
    fclose(fp); 
}
char *  readfile( char   * fn){
FILE 
* finPtr;
char  str[ 10240 ];
int  i;
finPtr
= fopen(fn, " r " ); // ./src.txt
i = readline(finPtr,str, sizeof (str));  // 示例中去掉只有回车的行
if (i == 1 )
fclose(finPtr);
return  str;
}
int  readline(FILE  * f, char   * str, int  strlen){
int  ch;
char   * tmp;
ch
= 0 ;
tmp
= str;
if (feof(f))
return   - 1 ;
while ( ! feof(f)  &&  ch != 0xa ){
ch
= fgetc(f);
if (ch != EOF  &&  ch != ' ' ){
* str = ch;
str
++ ;
}
}
if(*tmp==10 || *tmp=='/0' || *tmp=='/n')/* 如果行首字符等于ellipsis,返回错误代码 1 */
return 0;
else
return 1;
}

 

stack.h栈的结构文件,但我并没用上栈,不过这个文件里还是有几个函数有用的

 

#define  FALSE 0
#define  ERROR 0
#define  OK 1
#define  TRUE 1
#define  STACK_INIT_SIZE 30
#define  STACK_ADD 5
typedef 
int  Status;
typedef 
struct
{
char *top;
char *base;
int ssize;
}
 Stack;
void  msg( char   * c) {
    printf(
"%s ",c);
}

Stack 
* InitS(Stack  * s) {
    s
->base=(char *)malloc(STACK_INIT_SIZE*sizeof(char));
    
if(!s->base) msg("init error");
    s
->top=s->base;
    s
->ssize=STACK_INIT_SIZE;
    
return s;
}

void  DestS( Stack  * s) {
    s
->base=NULL;
    s
->top=s->base;
}

void  Push( Stack  * s, char  c)
{
    
if (s->top-s->base >= s->ssize) {
        s
->base = (char *)realloc(s->base ,(s->ssize +STACK_ADD)*sizeof(char));
        
if(!s->base ) msg("m error ");
        s
->top = s->base + s->ssize ;
        s
->ssize += STACK_ADD;
    }

    
*(s->top) = c;
    s
->top++;
}


 Stack 
* Pop( Stack  * s) {
    
if (s->top ==s->base ) msg("pop stack error");
        s
->top--;
    
return s;

}

char  Gettop( Stack  * s) {
    
return *(s->top -1);
}

Status Sempty( Stack 
* s) {
    
if (s->top ==s->base || s->top==NULL) 
        
return TRUE; 
    
else 
        
return FALSE;
}
  

hfm.h定义哈夫曼树的文件什么的。打印哈夫曼树那里还没打印成树形结构

 

typedef struct
{
    unsigned int weight;
 char code;
    unsigned int parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef char * *HuffmanCode;
void print(HuffmanTree HT,HuffmanCode HC,int n){
 int i,j,k;
 //printf("/n由于字符多于32且小于64个所以有小于2^6个/n所以每行有32个空格左有32个字符/n");
 for(i=1;i<=n;i++) {
 // for(j=0;j<32-i;j++)printf(" ");
 // for(j=1;j<=i;j++)
 //  for(i=1;i<=n;i++) {
 //   if (HC[i]
 //printf("%s ",HT[j].code);
 //  }
 printf(" %d %c %d %s/n",i,HT[i].code,HT[i].weight,HC[i]);
 }
}
void Select(HuffmanTree HT,int n,int *s1,int *s2){
 int i;
 (*s1)=(*s2)=0;
 for(i=1;i<=n;i++) {
  if(HT[i].weight<HT[(*s2)].weight&&HT[i].parent==0&&(*s2)!=0){
   if(HT[i].weight<HT[(*s1)].weight) {
    (*s2)=(*s1);
    (*s1)=i;
   } else
   (*s2)=i;
  }
  if(((*s1)==0||(*s2)==0)&&HT[i].parent==0) {
   if((*s1)==0)
    (*s1)=i;
   else
    if((*s2)==0) {
     if(HT[i].weight<HT[(*s1)].weight) {
      (*s2)=(*s1);
      (*s1)=i;
     } else
      (*s2)=i;
    }
  }
 } 
 if((*s1)>(*s2)) {
  i=(*s1);
  (*s1)=(*s2);
  (*s2)=i;
 }
 return;
}
void HuffmanCoding(HuffmanTree *HT,HuffmanCode *HC,int *w,char *code,int n) {
 int i,m,s1,s2,start,c,f;
 char *cd;
 if(n<=1) return;
 m=2*n-1;
 (*HT)=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
 for(i=1;i<=n;++i) {
  (*HT)[i].code=code[i-1];
  (*HT)[i].weight=w[i-1];
  (*HT)[i].parent=(*HT)[i].lchild=(*HT)[i].rchild=0;
 }
 for(;i<=m;++i) {
  (*HT)[i].code='0';
  (*HT)[i].weight=(*HT)[i].parent=(*HT)[i].lchild=(*HT)[i].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*sizeof(char*));
 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));
  strcpy((*HC)[i],&cd[start]);
 }
 msg(">哈夫曼编码初始化完毕");
}

show.h过程 的显示函数就在这里了

 

char showmenu(int i){
 char c[7]={' ',' ',' ',' ',' ',' ',' '};
c[i]='<';
printf("----------------------------------------/n");
printf("|          A.构造哈夫曼树%c             |/n",c[1]);
printf("|          B.对文件进行编码%c           |/n",c[2]);
printf("|          C.进行译码%c                 |/n",c[3]);
printf("|          D.打印文件%c                 |/n",c[4]);
printf("|          E.打印哈夫曼树%c             |/n",c[5]);
printf("|          F.退出%c                     |/n",c[6]);
printf("----------------------------------------/n");
return getch();
}
void printfile(){
    char *a;
 a=readfile(".//code.txt");
 msg(">开始打印文件");
 printf("编码部分为:");
 while(*a!='/0'){
  if(*a=='|')
   printf("/n字符串为:");
  else
   printf("%c",*a);
 a++;
 }
 printf("/n");
 msg(">打印文件完毕");
}
void Encoding(HuffmanTree HT,HuffmanCode HC,int n){
 char s[100];
 char out[1000];
 char *temp;
 int i=0,j;
 msg("请输入要进行编码的字符串:");
 scanf("%s",s);
 out[0]='/0';
 while(s[i]!='/0'){
  for(j=1;j<=n;j++) {
   if (s[i]==HT[j].code){
    temp=HC[j];
                strcat(out,temp);
   }
  }
  i++;
 }
 writefile(out,".//out.txt");
 msg(">保存编码后文件完毕");
 out[0]='/0';
 for(i=1;i<=n;i++){
    temp=HC[i];
    strcat(out,temp); }
 strcat(out,"|");
  strcat(out,s);
    writefile(out,".//code.txt");
    msg(">保存HC完毕");
}
void Uncoding(HuffmanTree HT,HuffmanCode HC,int n){
 char *a;
 int i=0,j=0,k,l=0;
 char out[1000];
 char temp[100];
 out[0]='/0';
 temp[0]='/0';
 a=readfile(".//out.txt");
 while(*a!='/0'&&*a!=0xa){ 
  temp[j]=*a;
  j++;
  for(k=1;k<=n;k++) {
   if (strcmp(temp,HC[k])==0){
    out[l]=HT[k].code;
    l++;
    while(j>=0){
     temp[j]='/0';
     j--;
    }
    j=0;
   }
  }
  a++;
 }
 out[l]='/0';
 msg(">译码完毕");
    printf(">译码结果为:%s/n",out);

}

main.c主函数

 

#include " head.h "
#include
" show.h "
main()
{
     
int i=0,n=28;
     
int w[28]={2,4,4,5,2,5,10,5,2,2,5
     ,
10,1,4,3,11,1
     ,
1,3,11,1,4,1,3,1,1,1,2}
;
     
char*str1, *str;
     
char c[28]={'a','b','c','d','e','f','g','h','i','j','k'
     ,
'l','m','n','o','p','q'
     ,
'r','s','t','u','v','w','x','y','z',' ','.'}
;
     
int j;
     
char key;
     HuffmanTree HT; 
     HuffmanCode HC;
    
while(1){
         
if (i<0) i=6;
         
if (i>6) i=1;
         key
=showmenu(i);
         system(
"cls");
         
if (key=='a'||key=='A'||(key==13&&i==1))
             HuffmanCoding(
&HT,&HC,w,c,n);
         
if (key=='b'||key=='B'||(key==13&&i==2))
             Encoding(HT,HC,n);
         
if(key=='c'||key=='C'||(key==13&&i==3))
             Uncoding(HT,HC,n);
         
if(key=='d'||key=='D'||(key==13&&i==4))
             printfile();
         
if(key=='e'||key=='E'||(key==13&&i==5))
             print(HT,HC,n);
         
if(key=='f'||key=='F'||(key==13&&i==6))
             exit(
0);
         
if(key==72)
            i
--;
         
if(key==80)
              i
++;
         
if(key==75)
            i
--;
         
if(key==77)
              i
++;
        
    }

     
    
return 1;
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值