【 数据结构 】哈夫曼树与哈夫曼编码

  • 定义:按照字符的频率(频数)构建最优树,即把频率小的树尽可能放在深层节点,频率大的树放在浅层节点,从而使得所有叶子节点的带权路径和最小。这样做的好处是依照路径重新对叶子节点的字符进行01编码,从而使高频率的字符编码短,低频率字符的编码长,这种不定长的编码可以使得最终文本长度减小,实现数据压缩;
  • // 树节点数据结构
    typedef struct tnode{
        char c;
        int weight;
        struct tnode *left, *right;	 //此时为链表
        // unsigned int left, right; //也可以为 int,此时为数组
    }

 

  • 哈夫曼树的构造:由于哈夫曼树是最优树,即节点的度为 0 或 2,因此具有 n 个叶子节点的树的总结点个数为 2n-1 个,对于具有 n 个字符的数据进行建树:
  1. 开辟长度为 2n+1 的数组空间arr, 1~n为叶子节点,n+1~2n 是非叶子节点,0 空间不使用;
  2. int m = n*2 - 1
    for(int i = n+1; i <= m; i++){
        select(arr, i-1, left, right); // 从 [1,i]间选择最小的两个子节点
        //令 left, right 分别为 i 的子节点
        //令 i 为 left, right 的父节点,权值为其和
    }
    // 即可完成树的构建,其中 arr[m]存放的是根节点

     

  • 获取字符的哈夫曼编码
  1. // 先序遍历树结构,路径即为结果
    char path[MAX_SIZE];
    char code[SIZE][MAX_SIZE]; // 存放所有字符的编码
    traversalHuffmanTree(&root, path, 0); // 获取编码
    
    void traversalHuffmanTree(tnode *root, char* path, int len){
        if(root == NULL)    return ;
        if(root->left == NULL && root->right == NULL){
            path[len] = '\0'; //叶子节点,结束符
            strcpy(code[root->c], path]); // 将编码赋值到 root 的字符对应编码位置
            return ;
        }
        // 左子树路径为 0
        path[len] = '0';
        traversalHuffmanTree(root->left, path, len+1);
        // 右子树路径为 1
        path[len] = 1;
        traversalHuffmanTree(root->right, path, len+1);
    }
    

     

  2. 文件压缩:依照编码依次对相应字符进行重新编码组成字符串,将每 8 位的字符串转化为 unsigned char 类型压缩存储

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值