从文本中统计字符权重并依次构建huffman树

本代码主要解决从指定文件中统计每个字符的权重并构建huffman树

 #include "stdafx.h"

#include "stdio.h"
#include "string.h"
#include"stdlib.h"
typedef struct  {
    int weight;//权重  
    int parent;//父节点  
    int lchild;//左孩子  
    int rchild;//右孩子  
}HTNode,*HuffmanTree;  
typedef char **HuffmanCode;


typedef struct{  
    char data;  
    int weight;  
}Node;  //用来存储每个字符的权重


void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *wet,int n)//构造赫夫曼树并求每一个字符的赫夫曼编码
{  
void select_minium(HuffmanTree HT,int k,int &min1,int &min2)  ;
int c,f;
if(n<=1)return;
int m=2*n-1;
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
for (int i=0;i<n;i++)
{
HT[i].parent = 0;  
        HT[i].lchild = 0;  
        HT[i].rchild = 0;  
        HT[i].weight = *wet;  //wet为一个数组
        wet++;  
}
for(;i<m;i++)
{
HT[i].parent = 0;  
        HT[i].lchild = 0;  
        HT[i].rchild = 0;  
        HT[i].weight = 0;  
}
int min1,min2;
for (i=n;i<m;i++)
{
select_minium(HT,i,min1,min2); 
HT[min1].parent=i;HT[min2].parent=i;
HT[i].lchild=min1;HT[i].rchild=min2;
HT[i].weight=HT[min1].weight+HT[min2].weight;
}
HC=(HuffmanCode)malloc((n+1)*sizeof(char*));//分配n个字符编码的头指针
char *code=(char *)malloc(n*sizeof(char)); //求编码的工作空间
if(!code)  
    {  
        printf("code malloc faild!");  
        exit(-1);  
    }  
  
    code[n-1] = '\0';  //编码结束符,亦是字符数组的结束标志  
    for (i=0;i<n;i++)
    {
int start=n-1;
for (c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)
{
if(HT[f].lchild==c) code[--start]='0';
else code[--start]='1';
}
HC[i]=(char*)malloc((n-start)*sizeof(char));
strcpy(HC[i],&code[start]);
    }
free(code);

}
void select_minium(HuffmanTree HT,int k,int &min1,int &min2)  //找最小的两个节点
{  
int min(HuffmanTree HT,int n);
    min1 = min(HT,k);  
    min2 = min(HT,k);  
}  
int min(HuffmanTree HT,int n)
{
int i = 0;  
    int min;        //用来存放weight最小且parent为0的元素的序号  
    int min_weight; //用来存放weight最小且parent为0的元素的weight值   
    while(HT[i].parent != 0)  
        i++;  
    min_weight = HT[i].weight;  
    min = i;  
  
    //选出weight最小且parent为-1的元素,并将其序号赋给min  
    for(;i<n;i++)  
    {  
        if(HT[i].weight<min_weight && HT[i].parent==0)  
        {  
            min_weight = HT[i].weight;  
            min = i;  
        }  
    }  
  
    //选出weight最小的元素后,将其parent置1,使得下一次比较时将其排除在外。  
    HT[min].parent = 1;   
  
    return min;  
}


int main(int argc, char* argv[])

void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *wet,int n);
   int i=0,n=0,j=0,m=0,temp=0;
   char ch;
   char All[438];
   int wet[100]={0};
   char *a=new char[100];


   FILE *fp1,*fp2,*fp3,*fp4,*fp5;
   if((fp1=fopen("message.txt","r"))==NULL)
   {
  printf("can not find the file\n");
  exit(0);
   }
    if((fp2=fopen("fequency.txt","w"))==NULL)
   {
  printf("can not find the file\n");
  exit(0);
   }
if((fp3=fopen("codes.txt","w"))==NULL)
   {
  printf("can not find the file\n");
  exit(0);
   }
 if((fp4=fopen("Mymessage.txt","r+"))==NULL)
   {
  printf("can not find the file\n");
  exit(0);
   }


   if((fp5=fopen("huffmancoding.txt","r+"))==NULL)
   {
  printf("can not find the file\n");
  exit(0);
   }
   ch=fgetc(fp1);
*a=ch;
    wet[0]++;
    n++;
while(!feof(fp1))
{
ch=fgetc(fp1);
        for(int i=0;i<n;i++)
{
if(ch==*(a+i)){wet[i]++;break;}
else if(i==n-1){n++;*(a+n-1)=ch;wet[n-1]=1;break;}
}
}
for(i=0;i<n;i++)
{
fprintf(fp2,"%c %d\n",*(a+i),wet[i]);
printf("%c %d\n",*(a+i),wet[i]);
}
HuffmanTree HT;HuffmanCode HC;
HuffmanCoding(HT,HC,wet,n);
    for (i=0;i<n;i++)
    {
printf("%c的编码 ",*(a+i));
fprintf(fp3,"%c的赫夫曼编码",*(a+i));
printf("%s\n",HC[i]);
fprintf(fp3,"%s\n",HC[i]);
    }
fclose(fp1);
    fp1=fopen("message.txt","r");

while(!feof(fp1))//huffman译码过程
{
          ch=fgetc(fp1);
for( i=0;i<n;i++)
{
if(*(a+i)==ch)
fprintf(fp5,"%s",HC[i]);
}
}
fclose(fp5);
 if((fp5=fopen("huffmancoding.txt","r+"))==NULL)
   {
  printf("can not find the file\n");
  exit(0);
   }
int v=2*n-2;
while(!feof(fp5))
{
 ch=fgetc(fp5);
 if(ch=='0')
 {
 v=HT[v].lchild;
 }
 else if(ch=='1')
 {
 v=HT[v].rchild;
 }
 if (HT[v].lchild==0&&HT[v].rchild==0)
 {
 fprintf(fp4,"%c",*(a+v));
 v=2*n-2;
 }
}
   fclose(fp1);
   fclose(fp2);
   fclose(fp3);
   fclose(fp4);
return 0;
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值