一文搞懂哈夫曼树

哈夫曼树介绍

hello,大家好,我是bigsai。

哈夫曼树、哈夫曼编码很多人可能听过,但是可能并没有认真学习了解,今天这篇就比较详细的讲一下哈夫曼树。

首先哈夫曼树是什么?

哈夫曼树的定义:给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree),哈夫曼树是带权路径长度最短的树。权值较大的结点离根较近。

那这个树长啥样子呢?例如开始2,3,6,8,9权值节点构成的哈夫曼树是这样的:

image-202106161****5069

从定义和图上你也可以发现下面的规律:

  • 初始节点都在树的叶子节点上
  • 权值大的节点离根更近
  • 每个非叶子节点都有两个孩子(因为我们自下向上构造,两个孩子构成一个新树的根节点)

你可能会好奇这么一个哈夫曼树是怎么构造的,其实它是按照一个贪心思想和规则构造,而构造出来的这个树的权值最小。这个规则下面会具体讲解。

哈夫曼树非常重要的一点:WPL(树的所有叶结点的带权路径长度之和)。至于为什么按照哈夫曼树方法构造得到的权重最小,这里不进行证明,但是你从局部来看(三个节点)也要权值大的在上一层WPL才更低。

WPL计算方法: WPL=求和(Wi * Li)其中Wi是第i个节点的权值(value)。Li是第i个节点的长(深)度.

例如上面 2,3,6,8,9权值节点构成的哈夫曼树的WPL计算为(设根为第0层):

比如上述哈夫曼树的WPL为:2*3+3*3+6*2+8*2+9*2=(2+3)*3+(6+8+9)*2=61.

既然了解了哈夫曼树的一些概念和WPL的计算方式,下面看看哈夫曼树的具体构造方式吧!

哈夫曼树构造

初始给一个森林有n个节点。我们主要使用贪心的思想来完成哈夫曼树的构造:

  1. 在n个节点找到两个最小权值节点(根),两个为叶子结构构建一棵新树(根节点权值为左右孩子权值和)
  2. 先删掉两个最小节点(n-2)个,然后加入构建的新节点(n-1)个
  3. 重复上面操作,一直到所有节点都被处理

在具体实现上,找到最小两个节点需要排序操作,我们来看看2,6,8,9,3权值节点构成哈夫曼树的过程。

初始时候各个节点独立,先将其排序(这里使用优先队列),然后选两个最小节点(抛出)生成一个新的节点,再将其加入优先队列中,此次操作完成后优先队列中有5,6,8,9节点

image-202106160****4144

重复上面操作,这次结束 队列中有11,8,9节点(排序后8,9,11)

image-202106160****7369

如果队列为空,那么返回节点,并且这个节点为整个哈夫曼树根节点root。

否则继续加入队列进行排序。重复上述操作,直到队列为空

image-202106160****3250

image-202106160****7977

在计算带权路径长度WPL的时候,需要重新计算高度(从下往上),因为哈夫曼树是从下往上构造的,并没有以常量维护高度,可以构造好然后计算高度。

具体代码实现

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;

public class HuffmanTree {    
    public static class node
    {
        int value;
        node left;
        node right;
        int deep;//记录深度
        public node(int value) {
            this.value=value;
            this.deep=0;
        }
        public node(node n1, node n2, int value) {
            this.left=n1;
            this.right=n2;
            this.value=value;
        }
    }
    private node root;//最后生成的根节点
    List<node>nodes;
    public HuffmanTre

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

图解数据结构与算法(Java) 文章被收录于专栏

让数据结构与算法学习更简单,每一种数据结构与算法通过多图的方式讲解、实现、解题,内容覆盖递归详解、单双链表、堆、栈、二叉树(遍历、插删)、AVL树、哈夫曼树、字典树、dfs、bfs、拓扑排序、Dijkstra、Floyd、并查集、跳表、分治算法、动态规划、快速幂、十大排序等等。 还覆盖超经典面试笔试题例如:topK问题、约瑟夫环问题、链表找环问题、LRU、20+道经典动态规划问题!

全部评论
确实懂了,感谢楼主
点赞 回复 分享
发布于 2022-07-05 18:44

相关推荐

点赞 评论 收藏
分享
11-07 13:31
怀化学院 Java
勇敢牛牛不怕难:又疯一个
点赞 评论 收藏
分享
评论
3
8
分享
牛客网
牛客企业服务