给定一篇英文文章,建立哈夫曼树进行压缩存贮,并且实现解码功能

话不多说,上代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct node    
{
 int bol,num;     
 char ch;            
 struct node* lchild;
 struct node* rchild;
 struct node* next; 
}NODE;
typedef struct node* Node;
Node header=NULL;         
int path[20],top=-1,k=0; 
char B[200];              
FILE* fp=NULL;
typedef struct ch        
{
 char chk;
 int digi[100];
}CH;
CH dictnory[500];         
char article()          
{ 
 gets(B);
 int len = strlen(B);
 int i,j,flag=0; 
 header = (Node)malloc(sizeof(NODE));
 header->next = NULL;
 Node p = header,q=header;        
 for (i = 0; i < len; i++)        
 {
  p = header;
  while (p->next!=NULL)
  {
   p = p->next;
   if (p->ch == B[i])
   {
    p->num++;
    flag = 1;
    break;
   }    
  }
  if (flag != 1)
  {
   Node pr = NULL;
   pr = (Node)malloc(sizeof(NODE));  
   pr->ch = B[i];
   pr->num = 1;   
   q->next = pr;
   q = pr;
   pr->next = NULL;
  }
  flag = 0;
 }
}
int lengh(Node header)        
{
 Node p=header;
 int i=0;
 while (p->next != NULL)
 {
  p=p->next;
  i++;
 }
 return i;
}
void sort(Node header)         
{
 int i,j,len=lengh(header),flag=0;
 Node p = header->next, pr = header;
 for (i = 0;i<len; i++)
 {
  p = header->next;
  pr = header;
  for (j = 0; j < len - i; j++)
  {
   if (p->next != NULL)
   {
    if (p->num > p->next->num)
    {
     pr->next = p->next;
     p->next = pr->next->next;
     pr->next->next = p;
     pr = pr->next;
     flag = 1;
    }
    if (flag == 0)
    {
     p = p->next;
     pr = pr->next;
    }
    flag = 0;
   }
   else break;
  }
 }
}
Node tree(Node header)       
{
 
 Node p = header->next,ph=header;
 while (ph->next != NULL)    
 {
  ph = ph->next;
  ph->lchild = NULL;
  ph->rchild = NULL;
 }
 while (p!=NULL)
 {
  Node p1;
  p1 = (Node)malloc(sizeof(NODE)); 
  p1->lchild = p;
  p1->rchild = p->next;
  p1->num = p->num + p->next->num;  
  p = p->next->next;
  header->next = p;
  p1->lchild->bol = 0;
  p1->rchild->bol = 1;
  p1->rchild->next = NULL;      
  p1->lchild->next = NULL;
  ph = header;
  while (ph->next != NULL && ph->next->num <= p1->num )
  {                                                   
   ph = ph->next;   
  }
  p1->next = ph->next;
  ph->next = p1;
 }
 return header->next;          
}
Node stack(Node head)       
{
 if (head != NULL)
 {
  path[++top] = head->bol;
  if (head->lchild == NULL && head->rchild == NULL)
  {
   printf("%c ", head->ch);
   dictnory[k].chk = head->ch;
   for (int i = 1; i <= top; i++)
   {
    dictnory[k].digi[i-1] =path[i];
    printf("%d", path[i]);
    dictnory[k].digi[i] = 2;
   }
   k++;
   printf("\n");
  }
  stack(head->lchild);
  stack(head->rchild);
  --top;
 } 
}
void coding()                  
{
 fp= fopen("D:/decode.txt", "wb");
 printf("\n");
 int i = 0,j=0,n=0;
 while (B[i]!='\0')
 {
  
  while (1)
  {
   if (dictnory[j].chk == B[i])
   {
    while (dictnory[j].digi[n] != 2)
    {
     //fwrite(dictnory[j].digi, sizeof(int), 1, fp);
     fprintf(fp, "%d", dictnory[j].digi[n]); 
     printf("%d", dictnory[j].digi[n]);     
     n++;
    }
    n = 0;
    break;
   }
   j++;  
  }
  j = 0;
  i++;
 }
 fclose(fp);
}
void Read()                
{
 header = (Node)malloc(sizeof(NODE));
 header->next = NULL;
 Node ph = header;
 Node p = NULL, pTemp = NULL;
 pTemp = (Node)malloc(sizeof(NODE));
 pTemp->next = NULL;
 fp = fopen("D:/tree.txt", "rb");
 fread(pTemp, sizeof(NODE), 1, fp);
 while (feof(fp) == 0)
 {
  p = (Node)malloc(sizeof(NODE));
  //strcpy(p->ch, pTemp->ch);
  p->ch = pTemp->ch;
  p->num=pTemp->num;
  ph->next = p;
  ph = p;
  fread(pTemp, sizeof(NODE), 1, fp);
 }
 ph->next = NULL;
 free(pTemp);
 fclose(fp);
 return;
}
void decoding()
{
 char digital[300], i = 0;
 Read();                           
 Node pk = tree(header);  
 Node p = pk;
 fp = fopen("D:/decode.txt", "r");
 while (fscanf(fp, "%c", &digital[i]) != EOF)  
 {
  printf("%c", digital[i]);          
  i++;
 }
 digital[i] = '\0';         
 printf("\n");
 i = 0;
 while (1)
 {
  while (1)
  {
   if (digital[i] == '0')       
   {
    p = p->lchild;
   }
   else if (digital[i] == '1')
   {
    p = p->rchild;
   }
   i++;
   if (p->lchild == NULL)    
   {
    printf("%c", p->ch);
    p = pk;
    break;
   }
  }
  if (digital[i] == '\0')
   break;
 }
}
int main()
{
 int se;
 printf("----提示: 要解码前必须先进行一次输入文章,以便建立储存哈夫曼树,并利用该哈夫曼树进行解码\n");
 printf("按1压缩文章,按其他解码\0"); 
 scanf("%d", &se);
 setbuf(stdin, NULL);  
 if (se ==1)
 {
  printf("请输入字符串\n");
  article();
  sort(header);
  save(header);             
  Node pk = tree(header);    
  stack(pk);                   
  printf("对应编码码为:\n");
  coding();
 }
 else
 {
  printf("文件的01序列对应解码为\n");
  decoding();
 }
 
}
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值