A simple test

哈夫曼编码


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

#include 
#include 
#include 
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;inext) {//形成哈夫曼树
        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;
}


你可能感兴趣的:(A simple test)