基于Huffman编码的C语言解压缩文件程序

基于Huffman编码的C语言解压缩文件程序

C++使用优先队列来构建huffman树[哈夫曼树]

Huffman编码实现(详细实现)

Huffman编码与解码的实现

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
            //极大值用于生成Huffman树
#define MAXSIZE 100000000
            //用于生成相应叶子节点Huffman编码的二维字符数组
typedef char* HCode;
            //Huffman树节点
typedef struct node
{
    int weight;
    int data;
    int parent,lchild,rchild;
}Node;
            //count 叶子节点数的计算  sum_bit 记录被压缩文件编码后的编码总长度
int sum_bit,count;
            //Huffman叶子节点,最多不过256个(以字节为单位)
Node huffmanNode[260];
            //解压缩的时候记录每次读取到编码(0....1..)
int num[8];
            //对应词频信息表的信息,用ASCII值表示
int code[260];
          //二维字符数组
HCode *HC;
            //统计词频时用于查找是否已经记录过,记录过的话返回下标,没有则返回0
int isInNode(int value)
{
    int i = 1;
    for(;i<=count;i++)
    {
        if(huffmanNode[i].data == value)
        {
            return i;
        }
    }
    return 0;
}
            //获取文件词频,记录在Node huffmanNode[260]的节点数组当中
void  calWeight(char *file)
{
    count = 0;
    FILE *f;
    int a;
            //以二进制方式打开文件,为了读取到换行符
    f = fopen(file,"rb");
    if(f == NULL)
    {
        printf("文件不存在!打开失败!");
        return ;
    }
    while(!feof(f))
    {
        a = fgetc(f);
        if(a==EOF) break;
        if(!isInNode(a))  //count从1开始计数
        {
            count++;
            huffmanNode[count].weight = 1;
            huffmanNode[count].data  = a;
        }
        else
        {
            int i = isInNode(a);
            huffmanNode[i].weight++;
        }
    }
    fclose(f);
}


/*得到待压缩文件的总字节数,权值为几就代表着有多少个字节*/
int getSumBytes()
{
    int i=1;
    int result = 0;
    for(;i<=count;i++)
    {
        result +=huffmanNode[i].weight;
    }
    return result;
}

//获取压缩后文件的总bit数
int getSumBits()
{
    int i = 1;
    int result = 0;
    for(;i<=count;i++)
    {
        result+=huffmanNode[i].weight * strlen(HC[i]);
    }
    return result;
}

//建立huffman树 根据huffman树的特性,具有n个节点的huffman树的具有2n-1个节点
            //n值由全局变量count值来确定,该函数主要用来初始化Huffman树的所有节点信息
void  createHufmanTree(Node * huffmanTree)
{
    int m = 2*count - 1;
    int m1,m2,x1,x2,i,j;
            //初始化结点信息,从1--count这count个节点信息为叶子节点的信息
    for(i=1;i<=count;i++)
    {

huffmanTree[i].data = huffmanNode[i].data;
        huffmanTree[i].lchild = -1;
        huffmanTree[i].rchild = -1;
        huffmanTree[i].parent = -1;
        huffmanTree[i].weight = huffmanNode[i].weight;
    }
            //从count---2*count-1这些节点首先初始化为空
    for(;i<=m;i++)
    {
        huffmanTree[i].data = 0;    huffmanTree[i].weight = 0;
        huffmanTree[i].lchild = -1; huffmanTree[i].rchild = -1;
        huffmanTree[i].parent = -1;
    }
            //构造huffman树,按照huffman树构建原理
    for(i=count+1;i<=m;i++)
    {
        /*m2,m1分别存储倒数第二小的权值和倒数第一小的权值
          x2,x1分别存储倒数第二小的下标和倒数第一小的下标*/
        m1 = m2 = MAXSIZE;
        x1 = x2 = 0;
        for(j=1;j<i;j++)
        {
            if(huffmanTree[j].parent == -1&&huffmanTree[j].weight <m1)
            {
                m2 = m1;                    x2 = x1;
                m1 = huffmanTree[j].weight; x1 = j;
            }
            else if(huffmanTree[j].parent == -1&&huffmanTree[j].weight<m2)
            {
                m2 = huffmanTree[j].weight;
                x2 = j;
            }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/a287560f1be06e4c9967e0a3f6500edb.html