哈夫曼树

基本介绍

1、哈夫曼树(最优二叉树):给定 n 个权值作为 n 个叶子结点,构造一棵二叉树,该树的带权路径长度达到最小

2、最优二叉树是带权路径长度最短的树,权值较大的节点离根较近

3、根据最优二叉树(哈夫曼树)构造过程可知,最优二叉树中只有度为 2 和 0 的结点

(1)已知叶子节点数为 n0

(2)根据二叉树性质,度为 2 的节点数 n2 = n0 - 1,即非叶子节点数为 n0 - 1

(3)总节点数 n = 2 * n0 - 1

 

概念

1、路径:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路

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

3、结点的权(权值):若给树中结点赋一个有着某种含义的数值

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

5、树的带权路径长度:规定为所有叶子结点的带权路径长度之和

 

构建最优二叉树

1、对数列从小到大进行排序,每个数据都是一个节点,每个节点都可以看成是一颗最简单的二叉树

2、取出根节点权值最小的两颗二叉树,将它们组成一颗新的二叉树。该新的二叉树的根节点的权值是前面两颗二叉树根节点权值的和

3、再将这颗新的二叉树,以根节点的权值大小回到序列再次排序

4、重复步骤 2、步骤 3,直到数列中,所有的数据都被处理,就得到一颗哈夫曼树

5、若初始森林中共有 n 棵二叉树,进行 n - 1 次合并后才能剩下一棵最终的哈夫曼树

 

代码实现

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class HuffmanTree {

    //创建赫夫曼树
    public static Node createHuffmanTree(int[] arr) {
        //遍历 arr 数组,将arr的每个元素构成成一个Node,放入到ArrayList中
        List<Node> nodes = new ArrayList<Node>();
        for (int weight : arr) {
            nodes.add(new Node(weight));
        }
        while (nodes.size() > 1) {
            //从小到大排序,直到剩余元素为1
            Collections.sort(nodes);
            //取出权值最小的结点
            Node leftNode = nodes.get(0);
            //取出权值第二小的结点
            Node rightNode = nodes.get(1);
            //构建一颗新的二叉树
            Node parent = new Node(leftNode.weight + rightNode.weight);
            parent.left = leftNode;
            parent.right = rightNode;
            //从ArrayList删除处理过的二叉树
            nodes.remove(leftNode);
            nodes.remove(rightNode);
            //将parent加入到nodes
            nodes.add(parent);
        }
        //返回哈夫曼树的root结点
        return nodes.get(0);
    }
}

//为了让Node对象,使用Collections的sort,让Node实现Comparable接口
class Node implements Comparable<Node> {
    int weight;//结点权值
    Node left;//指向左子结点
    Node right;//指向右子结点

    public Node(int weight) {
        this.weight = weight;
    }

    @Override
    public String toString() {
        return "Node{" +
                "weight=" + weight +
                '}';
    }

    @Override
    public int compareTo(Node o) {
        //从小到大排序
        return this.weight - o.weight;
    }
}

 

posted @   半条咸鱼  阅读(123)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示