赫夫曼树

Posted liuzhidao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了赫夫曼树相关的知识,希望对你有一定的参考价值。

基本介绍

  • 给定n个权值作为n个叶子节点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,这样的二叉树为最优二叉树,也称为赫夫曼树
  • 赫夫曼树是带权路径长度最短的数,权值较大的节点离根较近

赫夫曼树几个重要概念

  • 1.路径和路径长度:在一棵树中,从一个节点往下可以达到的孩子或孙子节点之间的通路,称为路径.通路中分支的数目称为路径长度.若规定根节点的层数为1,则从根节点到第L层节点的路径长度为L-1
    1. 节点的权及带权路径长度:若将树中节点赋给一个有着某种含义的数值,则这个数值称为该节点的权.节点的带权路径长度为:从根节点到该节点之间的路径长度与该节点的权的乘积.
    1. 树的带权路径长度:树的带权路径长度规定为所有叶子节点的带权路径长度之和,记为WPL,权值越大的节点离根节点越近
  • WPL最小的就是赫夫曼树
    技术图片

赫夫曼树创建思路图解

给你一个数列{13, 7, 8, 3, 29, 6, 1},要求转成一棵赫夫曼树.

构成赫夫曼树的步骤:

  • 从小到大进行排序,将每一个数据都是一个节点,每个节点可以看成是一棵简单的二叉树
  • 取出根节点权值最小的两颗二叉树
  • 组成一棵新的二叉树,该新的二叉树的根节点的权值是前面两颗二叉树根节点权值的和
  • 再将这棵新的二叉树,以根节点的权值大小再次排序,不断重复 上述步骤,知道数列中所有数据都被处理,就得到一棵赫夫曼树
    技术图片

代码实现

public class HuffumanTree {
    public static void main(String[] args) {
        int[] arr = {13, 7, 8, 3, 29, 6, 1};
        HuffumanNode root = createHuffumanTree(arr);
        //进行前序遍历,检测是否构建成功
        preOrder(root);

    }
    //前序遍历
    public static void preOrder(HuffumanNode root){
        if (root == null){
            System.out.println("赫夫曼树为空");
        }else {
            root.preOrder();
        }
    }
    //构建赫夫曼树
    private static HuffumanNode createHuffumanTree(int[] arr) {
        //1.遍历arr,将其放入list中,方便排序
        List<HuffumanNode> nodes = new ArrayList<>();
        for (int item:arr) {
            nodes.add(new HuffumanNode(item));
        }
        //集合中只有一个元素时,就表示赫夫曼树构建成功了,这个元素就是根节点
        while (nodes.size()>1){
            //排序
            Collections.sort(nodes);
            //取出集合前两个元素,即最小的两个元素
            HuffumanNode leftNode = nodes.get(0);
            HuffumanNode rightNode = nodes.get(1);
            //构成树
            HuffumanNode parent = new HuffumanNode(leftNode.val + rightNode.val);
            parent.left = leftNode;
            parent.right = rightNode;
            //从列表中删除取出的元素,并将paret添加到集合中
            nodes.remove(leftNode);
            nodes.remove(rightNode);
            nodes.add(parent);
        }
        return nodes.get(0);
    }
}

//因为需要进行排序,所以实现 Comparable 接口
class HuffumanNode implements Comparable<HuffumanNode>{
    int val; //值
    HuffumanNode left;  //左节点
    HuffumanNode right;  //右节点

    public HuffumanNode(int val) {
        this.val = val;
    }


    @Override
    public String toString() {
        return "HuffumanNode{" +
                "val=" + val +
                ‘}‘;
    }

    @Override
    public int compareTo(HuffumanNode o) {
        //从小到大
        return this.val-o.val;
    }

    //前序遍历
    public void preOrder(){
        System.out.println(this);
        if (this.left!=null){
            this.left.preOrder();
        }
        if (this.right!=null){
            this.right.preOrder();
        }
    }
}



以上是关于赫夫曼树的主要内容,如果未能解决你的问题,请参考以下文章

赫夫曼树的构建编码译码解析

数据结构与算法:树 赫夫曼树

数据结构与算法:树 赫夫曼树

学习数据结构笔记(10) --- [赫夫曼树(Huffman Tree)与赫夫曼编码(Huffman coding)]

数据结构与算法:树 赫夫曼树

数据结构与算法:树 赫夫曼树