在完成哈夫曼压缩项目的过程中,涉及到了一些数据结构和集合的知识。主要有哈夫曼树的建立(主要进行字符统计)、利用优先队列进行排序(字符频率决定压缩字节码长度)和集合框架(方便进行数据的处理)。
哈夫曼树
是什么
- 给定 n 个权值作为 n 个叶子结点,构造一棵二叉树, 若该树的带权路径长度(wpl) 达到最小,称这样的二叉树为
最优二叉树,也称为哈夫曼树(Huffman Tree), 还有的书翻译为霍夫曼树。 - 赫夫曼树是带权路径长度最短的树,权值较大的结点离根较近
有什么用
- 用于字符编码的压缩
- 个老木匠,有若干段长短不一的木头,他想把这些木头全部拼成一根,每次拼接耗费的体力是当前拼接的两段木头的长度,问老木匠最小花费多少体力。
- 相关贪心算法
…
怎么做
以哈夫曼压缩为例,每个字符在一段文字中有一定的出现频率,我们把这些频率作为相应的子节点的权值。进行排序后,将最小的两个相加构成一个新节点,其为最小两个节点的父节点。然后忽略两个孩子结点,再次排序,再次构树,以此循环
例如 {13, 7, 8, 3, 29, 6, 1}的哈夫曼树为:
优先队列
是什么
普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。通常采用堆数据结构来实现。
它和堆排序形影不离,首先它是由堆实现的,堆排序的基础就是它。不同在于优先队列是一种数据结构,它用于存储数据,在对数据进行操作时它的优点就会体现出来,而堆排序是一种排序算法。
有什么用
- 比方说我们有一个每日交易时段生成股票报告的应用程序,需要处理大量数据并且花费很多处理时间。客户向这个应用程序发送请求时,实际上就进入了队列。我们需要首先处理优先客户再处理普通用户
- 合并有序小文件
- 高性能定时器
- 堆排序
- 查找第K大(小)元素
- 在朋友和面试官面前装逼
怎么做
当我们向队列中插入一个数,我们可以把队列看成一个完全二叉树。即此处用n表示头结点,2n+1,2n+2表示孩子结点。然后从最后一个非叶子节点开始
从最后一个元素的父节点开始进行孩子爸爸比大小,最大或者最小(看你需求)当爸爸。然后新爸爸再向上比较,直到选出最大的一个。
堆排序就是它的延伸
将选出的最大值与队列最后的元素互换位置,然后重新开始“选拔”,将所有孩子选拔完之后,我们就已经将队列从小到大排列了