• 有趣的赫夫曼树


    美国有个数学家叫赫夫曼,60年前他根据数据的使用概率,发明了一个二叉树叫赫夫曼树。
    这个赫夫曼树被用在了数据压缩上,被称为赫夫曼编码,这是后来压缩的基础。
     
    他解决的问题主要思想是:根据元素出现的概率,获得最优解。
     
    举例如下:
    学生考试成绩出来后,会根据考试成绩分等级,极优秀,优秀,中等,及格,不及格。如果我们按照普通逻辑进行判断时,通常是:
     
        if (Score < 60) {
            printf("不及格");
        } else if (Score < 70) {
            printf("及格");
        } else if (Score < 80) {
            printf("中等");
        } else if (Score < 90) {
            printf("优秀");
        } else if (Score < 100) {
            printf("极优秀");
        }
    但是按照分数的分布概率,优秀:30%,中等:40%,及格:15%,极优秀:10%,不及格:5%
    如果先判断优秀,中等,再判断极优秀,极优秀,不及格,则可以提高很多效率。
    赫夫曼树就是根据概率来生成的二叉树。
    转换成二叉树区别如下:
     
    从根节点出发,遍历每一个叶子节点,是的到达节点时走的链接树乘以节点(nodeLinkNum * weight)对应的权重之和最小
    如:
    sum = 1*5+2*15+3*40+4*30+4*10
    显然,左图和右图总和不一样,左图的和大于右图.
     
    那给你一组数字,怎么构造一个赫夫曼树呢?
    1.先把所有的数据节点,从小到大依次排列,成为一个有序列表
    2.取出前面两个节点,让这两个节点的权重数据相加得到一个和,令这个和为根节点,这个两个节点的小的为其左孩子,大的为其右孩子
    3.令这个和节点替换掉前面的两个节点,并重新排序,生成一个有序列表
    4.不断重复第二步,第三步。直到所有的节点都被用完,得到一个排序结果,此时生成的二叉树,就是赫夫曼树。
     
     
    赫夫曼树的实际应用:压缩数据
    数据在计算机的表示形式是0,1,那么一串字符串的表示是怎么样的呢
    例如ABCDEF编码如下:
    那么要表示字符串“BADCADFEED”的二进制为:“001000011010000011101100100011”。
    但是ABCDEF做为基本字符,在这串字符串中的出现概率是不一样的,那么我们是否可以以概率做为字符权重,对字符生成赫夫曼树呢
     
    假设六个字母的频率为A 27,B 8,C 15,D15,E 30,F 5,合起来正好是100%。那就意味着,我们完全可以重新按照赫夫曼树来规划它们。
     
     
    将权值左分支改为0,右分支改为1后的赫夫曼树。
     
    根据重新编码后为:
    1001010010101001000111100(共25个字符)
    而原来的字符编码为:
    “001000011010000011101100100011”(共30个字符)
    压缩了近17%
     
    解压时,按照同样的规则,还原原字符串。
     
     
  • 相关阅读:
    用Visual C#创建Windows服务程序(转)
    输入字符串的格式不正确(异常详细信息: System.FormatException: 输入字符串的格式不正确。)
    pv操作二
    双进程struct sigaction中mask阻塞信号
    pv操作一
    sigprocmask
    共享内存二
    面向接口编程
    类之间的几种关系
    sigaction函数一
  • 原文地址:https://www.cnblogs.com/zhou--fei/p/10005253.html
Copyright © 2020-2023  润新知