学完了huffman树,讲一下自己对它的理解
- huffman树遵循二叉树的原则,每个节点最多有两个子节点,但是每个节点都带有一个权重,如果我们要将一组字符串 “ B D C A F E ” 插入huffman树,每个字符都会带有一个权重,“ B(8)D(15)C(15)A(27)F(5)E(30)”
- 首先要根据字符的权重从小到大排序,得到 “ F(5)B(8)C(15)D(15)A(27)E(30)” ,然后取出最小的两个,F和B ,从树的叶子节点开始插,然后得到F和B 的权重和 13 当做他们的父节点,这时候再把13和之前的字符串重新排序,重新取出两个权重最小的节点出来拼接(注:取出来的节点要从原数据里删除),如果取出来的两个里有之前的13(父节点),就把另一个和它一块组合成两个孩子节点继续往上走,刚才这里会走到下图的13和C那边,C的权重比13大,所以在右边,小即左边,继续往上走时从字符串里取出了两个最小的D(15)和A(27) 都比刚才的28小,他们和28没有关联,所以会另外生成一个新的父节点(权重42),然后再取得时候才会取到28和E(30),他们合成的父节点58,最后字符串里只剩下2个无名节点(我们不需要关注的节点),最后全部插入结果如 图一:
- 我们会发现我们需要的数据会全部插在叶子节点上!这个有什么用呢,如果我们把树从根节点往下查找数据,往左走用0来表示, 右用1来表示,那么生成的编码都将是唯一的!
- 看 图二:
-
比如D在此树的编码会是00,A 01,E 11,C 1101,F 1000,B 1001
-
所以利用huffman树这一规则,我们可以来做压缩,压缩通俗的讲就是把内容转化成占内存空间更小的字节,比如01。
-
下面我们用代码写出一颗哈夫曼树:
-
树的节点里和二叉排序树一样 有值、左右孩子、父节点 这里加了一个权重,用来判断树的存放位置的,节点里有个比大小的方法compareTo
public class HuffmanTree<Y> {
public TreeNode<Y> root; //根节点
private String defaultParentItem = "Y";
/**
* 节点
*
* @param <Y> 值
*/
public static class TreeNode<Y> implements Comparable<TreeNode<Y>> {
Y item;