霍夫曼编码及实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014686462/article/details/49330747

什么是霍夫曼编码:

哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)。

用处:

压缩文本

构造思路:

  • 根据给定的n个权值Wi,构成n 颗二叉树的集合F,其中每颗二叉树只对应一个节点,其左右子树问空

  • F中选取两颗根权值最小的二叉树作为左右子树构造一颗新的二叉树,新的二叉树根节点的权值为其左右子树根节点的权值之和。

  • F中删除这两颗子树,同时将新的二叉树加入集合F.
  • 重复2,3,知道集合F中只有一颗二叉树为止,这棵树便是霍夫曼树。

实现代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <stdlib.h>
#include <limits.h>
#include <time.h>
using namespace std;
const int MAX = INT_MAX;
const int MAX_LEN = 100;
typedef struct node
{
    int val;
    int lchild,rchild,parent;
    node() {
        val = 0;
        lchild = rchild = parent = -1;
    }
    node(int _v,int _l,int _r,int _p) {
        val = _v,lchild = _l,rchild = _r,parent = _p;
    }
}Hnode;
typedef struct Hcode
{
    int bit[MAX_LEN];
    int start;
}Hcode;
void HuffmanCoding(int w[],int n)
{
    if(n <= 1) return ;
    int i,j,m = 2*n -1;
    Hnode *H;
    H = (Hnode *)malloc(m*sizeof(Hnode));
    for(i = 0;i < m;i ++) {
        H[i] = node((i<n?w[i]:0),-1,-1,-1);
    }
    /*构造霍夫曼树*/
    for(i = n;i < m; i++) {
        int m1 = MAX, m2 = MAX;
        int x1 = -1,x2 = -1;
        for(j = 0;j < i;j ++) {
            if(H[j].parent != -1) continue;
            if(H[j].val < m1) {
                m2 = m1, m1 = H[j].val;
                x2 = x1, x1 = j;
            }
            else if(H[j].val < m2) {
                m2 = H[j].val, x2 = j;
            }
        }
        H[i] = node(m1+m2,x1,x2,-1);
        H[x1].parent = H[x2].parent = i;
    }
    /*霍夫曼编码*/
    Hcode *HC;
    HC = (Hcode *)malloc(n*sizeof(Hcode));
    for(i = 0;i < n;i ++) {
        int cnt = n-1;
        for(int s = i;s != -1;s = H[s].parent) {
            int p = H[s].parent;
            if(p == -1) break;
            if(H[p].lchild == s) HC[i].bit[cnt--] = 0;
            else {
                HC[i].bit[cnt--] = 1;
            }
        }
        HC[i].start = cnt + 1;//记录编码的起始位置
    }
    /*测试*/
    /*
    for(int i = 0;i < n;i ++) {
        cout<<"第"<<i<<"个字符编码为:\n";
        for(int j = HC[i].start;j < n;j ++) {
            cout<<HC[i].bit[j]<<" ";
        }
        cout<<"\n";
    }
    */
}
int main()
{
    /*测试*/
    srand((unsigned int)time(NULL));
    int *w,n = 1 + rand()%20;
    w = (int *)malloc(n*sizeof(int));
    for(int i = 0;i < n;i ++) {
        w[i] = 1 + rand()%100;
        cout<<w[i]<<endl;
    }
    HuffmanCoding(w,n);
    return 0;
}
阅读更多

扫码向博主提问

forever_24

非学,无以致疑;非问,无以广识
  • 擅长领域:
  • 机器学习
  • 统计分析
去开通我的Chat快问

没有更多推荐了,返回首页