A simple test

哈夫曼编码


此代码用于生成哈夫曼树并且获取哈夫曼编码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char buffer[100010];
typedef struct node
{
    int cnt;
    char *s;
    struct node *left,*right,*next;
} HuffmanNode;
HuffmanNode* Root=NULL;
HuffmanNode Trees[200];
HuffmanNode* createNode()
{
    HuffmanNode* p = (HuffmanNode*)malloc(sizeof(HuffmanNode));
    p->cnt = 0;
    p->left=p->right=p->next=NULL;
    return p;
}
void InsertLinkedList(HuffmanNode* p)//插入有序链表中
{
    HuffmanNode* q = Root,*front=NULL;
    if (Root==NULL) {
        Root=p;
    } else {
        if (p->cnt < Root->cnt) {
            p->next = Root;
            Root = p;
        } else {
            while (q && q->cnt <= p->cnt) {//保证相等权值的结点总是后插入的在后面
                front = q;
                q = q->next;
            }
            p->next = front->next;
            front->next = p;
        }
    }
}
void getHuffmanCode(HuffmanNode* p,char *temp,int i) {//得到字符的Huffman编码
    if (p->left==NULL && p->right==NULL) {//只有在叶节点时才停止
        temp[i]=0;
        p->s = (char *)malloc(strlen(temp)+1);
        strcpy(p->s,temp);
        return;
    } else {
        temp[i]='0';
        getHuffmanCode(p->left,temp,i+1);//沿左子树,Huffman编码加一个'0'
        temp[i]='1';
        getHuffmanCode(p->right,temp,i+1);//沿右子树,Huffman编码加一个'1'
    }
}
int main()
{
    FILE* fin = fopen("input.txt","r");
    FILE* fout = fopen("output.txt","w");
    int i,len,j=0,t=0;
    char temp[1000];
    unsigned char hc=0;

    Trees[0].cnt = 1;//让'\0'权值为1
    len = fread(buffer,1,100000,fin);//统计每个字符的频率
    for (i=0;i<len;i++) {
        if (buffer[i]!='\n') {
            Trees[buffer[i]].cnt++;
        }
    }

    for (i=0;i<200;i++) {//ascii码值从小往大插入,保证了相等的权值下,ascii码值小的在前面
        if (Trees[i].cnt) InsertLinkedList(&Trees[i]);
    }

    while (Root->next) {//形成哈夫曼树
        HuffmanNode *p = Root,*q = Root->next;
        Root = Root->next->next;
        HuffmanNode *T = createNode();
        T->cnt = p->cnt+q->cnt;
        T->left = p;
        T->right = q;
        InsertLinkedList(T);
    }

    getHuffmanCode(Root,temp,0);//获取哈夫曼编码

    for (i=0;i<=len;i++) {//输出结果
        if (buffer[i]!='\n') {
            j=0;
            while (Trees[buffer[i]].s[j]) {
                hc = (hc<<1) | (Trees[buffer[i]].s[j++]-'0');//注意此处右移的用法
                t++;
                if (t==8) {//8位一输出
                    printf("%x",hc);
                    fputc(hc,fout);
                    hc=0;
                    t=0;
                }
            }
        }
    }
    while(t>0) {
        hc = hc<<1;
        t++;
        if (t==8) {
            printf("%x",hc);
            fputc(hc,fout);
            break;
        }
    }
    return 0;
}


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 174,503评论 25 709
  • 最近在看图像的压缩,就想着先实现一个jpeg文件的解码。本来以为这种资料在网上会一搜一大堆,但搜了之后才发现很多网...
    月夢書阅读 11,123评论 6 14
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,253评论 19 139
  • 你没看错,今天的读书日志不讲大道理,也不讲小案例。只为有“小姐姐”需求的小伙介绍一位国外大牛,看看人家是如何靠一条...
    Null_Point阅读 547评论 0 1
  • 1.什么是库,为什么使用库? 库是共享程序代码的方式,一般分为静态库和动态库;库实现了iOS程序的模块化,将某些特...
    公子墨香阅读 11,648评论 18 60