堆排序&赫夫曼树&赫夫曼编码表的制取

树结构的实际应用

利用大顶堆实现排序(堆排序)

  • 大顶堆定义:即整个树中每个父节点都比其两个子节点要大(小顶堆就相反)
    在这里插入图片描述

  • 升序使用大顶堆,降序使用小顶堆

  • 原理图
    在这里插入图片描述
    在这里插入图片描述

  • 实例演示
    在这里插入图片描述

  • 效率:特别快,时间复杂度为O(nlogn)

赫夫曼树(HuffmanTree)

前提知识

  • 路径
    在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。

  • 路径长度
    通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为 L -1

  • 结点的权
    若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。

  • 带权路径长度

    • 结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积

    • 在这里插入图片描述

    • 树的带权路径长度:所有叶子结点的带权路径长度的和;也叫WPL(weighted path length)

定义

  • 给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长( wpl )达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树( Huffman Tree ),还有的书翻译为霍夫曼树

  • 简单来讲,Wpl最小的树称为霍夫曼树

  • 赫夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

  • 霍夫曼树只有一个根节点

  • 如图,中间为13,7,8,3的霍夫曼树
    在这里插入图片描述

将数组转为赫夫曼树

  • 简单来讲:就是将数组每个值作为树中的某个叶子结点,并且要使该树的wpl最小

  • 实现过程:

    • 简单来讲:先将数组元素对应的节点放进Arraylist后依照权值排序,如从小到大,然后先拿出前两个(两个最小的),然后新建一个父节点,该节点的权值为这两个的和,然后令其为该两个节点的父节点,接着将该父节点放入list中,然后将list中的这两个节点移出;接着就是不断的重复,再次排序,拿出前两个,构建新的父节点,放入,移出原来两个,重复直到list中只剩下一个节点(该节点即为霍夫曼树的根节点)
  • 实例演示

    • 节点类:继承comparable接口重写其方法,以至于能够使用Collections进行排序
    • 转赫夫曼树方法
      在这里插入图片描述

测试:转成赫夫曼树后进行前序遍历
-在这里插入图片描述

  • 结果:即该图从67开始的前序遍历顺序
    在这里插入图片描述

赫夫曼编码表的制取

各种编码的作用

  • 将数据转换成计算机能够识别的01语言

以一句字符窜来解释三种编码:将i like like like java do you like a java转成01

  • 定长编码

    • 简单来讲,就是将这句话中的每个字符转变为其ACSII码形式,然后再将这整串ACSII码转为二进制

    • 如图
      在这里插入图片描述

    • 通过定长编码得到的二进制信息为359位

  • 变长编码

    • 简单来讲,就是先计算这句话中每个字符出现的次数,然后根据次数的多少,令每个字符等于一个对应的二进制数,出现次数越多,对应的而进制数应该越简单,以此来实现转码

    • 如图
      在这里插入图片描述

    • 可以看出,通过变长编码的转码后不是一个前缀编码,如,e的编码为11,而o、v的编码前缀有11,这会导致识别出错,解决方法就是使用赫夫曼编码

      • 前缀编码定义:一个字符的编码不能是其他字符编码的前缀
  • 赫夫曼编码

    • 原理:与变长编码前面类似,先将句子中每个字符的出现次数进行统计,得到后,将每个字符出现的次数作为节点的权值,字符作为节点的数据,将所有次数转为一个赫夫曼树(这里可以类比前面将所有次数作为一个数组,然后按前面将数组转为赫夫曼树的过程转化),根节点的路径为0,往右的路径为1,到达次数节点的路径的这些01组合起来即为对应的赫夫曼编码
      在这里插入图片描述

      • 如图,j的赫夫曼编码为0000在这里插入图片描述
    • 赫夫曼编码是前缀编码,不会出现识别有歧义的情况,因此是无损压缩

    • 通过赫夫曼编码后的二进制信息个数为133,从359压缩到133,压缩了大约60%,压缩率通常在百分之20到90%之间

    • 注意,这个赫夫曼树根据排序方法不同,也可能不太一样,这样对应的赫夫曼编码也不完全一样,但是 wpl 是一样的,都是最小的

      • 如1,3,4,4,4,4,6,9这组数组,当1,3取出形成新的二叉树的父节点权值为1+3=4,放入4,4,4,4,6,9后,有多种排序方式,因为有多个4,所以可以放在这些4的前面或者中间或者后面,这样形成的her服慢速是不同的

赫夫曼编码表的获取

  • 原理前面提到了

  • 实例演示

    • 节点类:权值,字符(byte),左右节点

    • 将byte数组转为节点list

    • 将节点list转为赫夫曼树(前面已经提到了)

    • 将赫夫曼树转为赫夫曼编码表(以map的形式)
      在这里插入图片描述

      • 此处的stringbuilder的创建需要注意
  • 测试
    在这里插入图片描述

    • 结果:赫夫曼编码表
      在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值