哈夫曼編碼(C++語言)

#include
#include<stdlib.h>
#define MAX 27
typedef struct
    {
      char data;
   long weight;
   long parent;
   long left;
   long right;
    }huffnode;
typedef struct
{
 char cd[MAX];
    int start;
}huffcode;
void save(huffnode huff1[2*MAX])//**************************保存哈樹****************************
{
    FILE *p;
    int i;
    p=fopen("hfmTree.txt","wb");
    for(i=0;i<2*MAX;i++)
    fwrite(&huff1[i],sizeof(huffnode),1,p);
    fclose(p);
}
void read(huffnode huff2[2*MAX])//**********************************讀哈樹***************************************
    {
 
 FILE *p;
    int i;
    p=fopen("hfmTree.txt","rb");
    for(i=0;i<2*MAX;i++)
    {
  fread(&huff2[i],sizeof(huffnode),1,p);
  //printf("%10c%10d%10d%10d%10d",huff2[i].data,huff2[i].left,huff2[i].parent,huff2[i].right,huff2[i].weight);
 }
    fclose(p);
    }
void inputs()//*************************編碼字符串的輸入************************************
 {
  printf("請輸入要編碼的字符串,以#結束:");
  getchar();
  FILE *fp;
  char ch;
  fp=fopen("ToBeTran.txt","w");
  //ch=getchar();
  ch=getchar();
  while(ch!='#')
 {
  fputc(ch,fp);
  ch=getchar();
 
    }
    fclose(fp);
 }
void outputs(char a[1000])//*******************************譯嗎碼字符串讀出***********************
 {
  int i=0;
  FILE *fp;
  char ch;
  fp=fopen("ToBeTran.txt","r");
  ch=fgetc(fp);
  while(ch!=EOF)
  {
   //printf("%c",ch);
   a[i]=ch;
   i++;
   ch=fgetc(fp);
  }
  fclose(fp);
 }
void disp()//******************************打印樹
{    huffnode huff[2*MAX];
 read(huff);
    int top1;
 huffnode stack[100],p;
 int level[100],top,n,i;
 if (huff!=NULL)
 {
  printf("該二叉樹表示法:/n");
  top=1;
  stack[top]=huff[2*MAX-1];
  level[top]=3;
  while(top>0)
  {
   p=stack[top];
   n=level[top];
   for(i=1;i<=n;i++)
    printf(" ");
    printf("%d/n",p.weight);
   top--;
   if (p.right!=NULL)
   {
    top++;
    top1=p.right;
    stack[top]=huff[top1];
    level[top]=n+3;
   }
   if (p.left!=NULL)
   {
    top++;
    top1=p.left;
    stack[top]=huff[top1];
    level[top]=n+3;
   }
  }
 }
 printf("/n");
}
void outputsb(char a[1000])//*******************************編碼字符串讀出***********************
 {
  int i=0;
  FILE *fp;
  char ch;
  fp=fopen("CodeFile.txt","r");
  ch=fgetc(fp);
  while(ch!=EOF)
  {
   //printf("%c",ch);
   a[i]=ch;
   i++;
   ch=fgetc(fp);
  }
  fclose(fp);
 }
void code()//編碼***************************************************************
{  
 FILE *p;
    p=fopen("CodeFile.txt","w");
    fclose(p);
 huffnode ht[2*MAX];
 huffcode d,hcd[MAX];
 char a[100];
 int j,f,c,k,i;
 read(ht);
    inputs();
 outputs(a);
for(j=0;j<sizeof(a);j++)
{
 for(i=1;i<=MAX;i++)
 {if(a[j]==ht[i].data)
  {d.start=MAX+1;
      c=i;
      f=ht[i].parent;
      while(f!=0)
   {
      if(ht[f].left==c)
     d.cd[--d.start]='0';
      else
     d.cd[--d.start]='1';
      c=f;
      f=ht[f].parent;
   }
      hcd[i]=d;
//printf("輸出哈夫曼編碼:/n");
//for(i=1;i<=MAX;i++)
// printf("%c:",ht[i].data);
  
      for(k=hcd[i].start;k<=MAX;k++)
   {FILE *fp;
    char ch;
    ch=hcd[i].cd[k];
    fp=fopen("CodeFile.txt","a");
    fputc(ch,fp);
    fclose(fp);
         }
        
 //printf("/n");
 }
}
}
}
void decode()//譯碼**********************************************************
{  
 FILE *p;
    p=fopen("TextFile.txt","w");
    fclose(p);
 int k;
 char a[100];
 for(k=0;k<100;k++)
  a[k]='2';
 huffnode huff[2*MAX];
 read(huff);
 outputsb(a);
 int i,m,j;
 i=0;
 m=2*MAX-1;
  j=m;
 //while(a[i]!=EOF)
  //{ 
       
  //if (b!=EOF)
  while(a[i]!='2')
        {//b=int(a[i]);
  if(a[i]=='0')
   j=huff[j].left;
  else
   j=huff[j].right;
  if(huff[j].right==0)
  {
   printf("%c",huff[j].data);
   j=m;
   FILE *fp;
      char ch;
      ch=huff[j].data;
      fp=fopen("TextFile.txt","a");
      fputc(ch,fp);
      fclose(fp);
  }
 
  i++;
 }
  printf("/n");
}
void print()//打印代碼******************************************************
{
    int i=0;
  FILE *fp;
  char ch;
  fp=fopen("CodeFile.txt","r");
  ch=fgetc(fp);
  while(ch!=EOF)
  {
   char a[100];
   printf("%c",ch);
   a[i]=ch;
   i++;
   ch=fgetc(fp);
   if(i%50==0)
    printf("/n");
  }
  fclose(fp);
  printf("/n");
}
void main()
{
   int x;
   puts("*******************哈夫曼編/譯碼器演示******************************");
   while(1){
start:
   puts("1. 初始化      2. 編碼       3. 譯碼      4.打印代碼    5. 打印樹     6.退出");
   while(scanf("%d",&x)!=1)
   {
      while(getchar()!='/n')
      continue;
       puts("輸入錯誤!");
      puts("請重新輸入!");
      puts("1. 初始化      2. 編碼       3. 譯碼    4.打印代碼   5. 打印樹     6.退出");
    }
   switch (x)
   {
       case 1:
          goto settree;
         break;
       case 2:
          code();
         break;
      case 3:
          decode();
          break;
      case 4:
          print();
          break;
      case 5:
           disp();
     break;
   case 6:
     exit(0);
      default:
          puts("輸入錯誤!");
         puts("請重新輸入!");
         goto start;
    }
}
settree:
 huffnode ht[2*MAX],huff[2*MAX];
    huffcode hcd[MAX],d;
    int i,k,f,l,r,n,c,m1,m2;
    printf("元素個數:");
    scanf("%d",&n);
    for(i=1;i<=n;i++)
 {
  getchar();
     printf("第%d個元素=>/n/t結點值:",i);
     scanf("%c",&ht[i].data);
     printf("/t權重:");
     scanf("%d",&ht[i].weight);
 }
 //***********************************樹的錄入******************************************
 for(i=1;i<=2*n-1;i++)
    ht[i].parent=ht[i].left=ht[i].right=0;
 for(i=n+1;i<=2*n-1;i++)
 {
 m1=m2=32767;
 l=r=0;
 for(k=1;k<=i-1;k++)
  if(ht[k].parent==0)
   if(ht[k].weight<m1)
   {
             m2=m1;
    r=l;
    m1=ht[k].weight;
    l=k;
   }
   else if(ht[k].weight<m2)
   {
    m2=ht[k].weight;
    r=k;
   }
   ht[l].parent=i;
   ht[r].parent=i;
   ht[i].weight=ht[l].weight+ht[r].weight;
   ht[i].left=l;
   ht[i].right=r;
 }
 for(i=1;i<=n;i++)
 //printf("%10c%10d%10d%10d%10d",ht[i].data,ht[i].left,ht[i].parent,ht[i].right,ht[i].weight);
for(i=1;i<=n;i++)
{
 d.start=n+1;
 c=i;
 f=ht[i].parent;
 while(f!=0)
 {
  if(ht[f].left==c)
   d.cd[--d.start]='0';
  else
   d.cd[--d.start]='1';
  c=f;
  f=ht[f].parent;
 }
 hcd[i]=d;
}
printf("輸出哈夫曼編碼:/n");
for(i=1;i<=n;i++)
{
 printf("%c:",ht[i].data);
 for(k=hcd[i].start;k<=n;k++)
  printf("%c",hcd[i].cd[k]);
 printf("/n");
}
save(ht);
//read(huff);
//code();
//decode();
goto start;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章