千家信息网

Java怎样实现赫夫曼树的创建

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章给大家介绍Java怎样实现赫夫曼树的创建,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、赫夫曼树是什么?给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长
千家信息网最后更新 2026年11月01日Java怎样实现赫夫曼树的创建

这篇文章给大家介绍Java怎样实现赫夫曼树的创建,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

一、赫夫曼树是什么?

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

图1 一棵赫夫曼树

1.路径和路径长度

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

例如图1根节点到b节点之间的通路称为一条路径。

在一条路径中,每经过一个结点,路径长度都要加 1 。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。

例如图1根节点到c节点的路径长度为 4 - 1 = 3

2.节点的权和带权路径长度

若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。

例如图1中abcd节点的权值分别为12、5、6、21

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

例如图1节点c的带权路径长度为 3 * 6 = 18

3.树的带权路径长度

树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL。

例如上图中的树的WPL = (5 + 6)* 3 + 12 * 2 + 21 = 78

二、创建赫夫曼树

1.图文创建过程

假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为:

例如有四个叶子节点 a b c d 权值分别为 12、5、6、21

创建赫夫曼树前森林如下

(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);

(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;

在森林中取出 b c节点 形成一棵新树M

(3)从森林中删除选取的两棵树,并将新树加入森林;

将新树M添加到森林后 森林如下

(4)重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。

** 4.1重复步骤(2)

在森林中取出权为11的节点以及a节点组成一棵新树N

** 4.2重复步骤(3)

将新树N添加到森林中 森林如下

** 4.3重复步骤(2)

在森林中取出b节点和权为23的节点组成一棵新树S

则新树S就是我们要创建的赫夫曼树

2.代码实现

创建赫夫曼树的过程中,为确保每次从森林中取出的节点为最小值,这里采用快速排序算法,每次取出节点前,将森林中的树按照权值从小到大重新排列一次

节点的结构如下:

class Node implements Comparable {    private int element; //节点的权    private Node left; //节点的左子树    private Node right; //节点的右子树    //构造器    public Node(int aElement) {        this.element = aElement;    }    public int getElement() {        return element;    }    public void setElement(int element) {        this.element = element;    }    public Node getLeft() {        return left;    }    public void setLeft(Node left) {        this.left = left;    }    public Node getRight() {        return right;    }    public void setRight(Node right) {        this.right = right;    }    //前序遍历    public void preOrder() {        System.out.print(this + " ");        if (this.getLeft() != null) {            this.getLeft().preOrder();        }        if (this.getRight() != null) {            this.getRight().preOrder();        }    }    @Override    public String toString() {        return element + "";    }    @Override    public int compareTo(Node o) {        return this.getElement() - o.getElement(); //从小大到排序    }}

完整代码如下:

package com.xx.huffmantree;import java.util.*;/** * @author 谢鑫 * @version 1.0 * @date 2021/12/7 16:31 * 赫夫曼树 */public class HuffmanTreeDemo {    public static void main(String[] args) {        int[] arr = {12, 5, 6, 21};        HuffmanTree huffmanTree = new HuffmanTree();        Node root = huffmanTree.creTree(arr);        huffmanTree.preOrder(root);    }}class HuffmanTree {    public Node creTree(int[] aArr) {        List list = new ArrayList<>(); //用于存放数组元素        //将数组放存放list中        for (int element : aArr) {            list.add(new Node(element));        }        while (list.size() > 1) { //循环创建树            Collections.sort(list); //从小到大排序            //从list中从小取出两个节点            Node left = list.get(0);            Node right = list.get(1);            //初始化小树根节点            Node root = new Node(left.getElement() + right.getElement()); //小树根节点为左右子树节点element值的和            //构建小树            root.setLeft(left);            root.setRight(right);            list.add(root); //将小树根节点再次添加到list中            //移除集合中已经参与构建过树的节点            list.remove(left);            list.remove(right);//            list.remove(0);//            list.remove(0);  //取出两个队头元素 也可        }        return list.get(0);    }    //前序遍历    public void preOrder(Node aRoot) {        if (aRoot != null) {            aRoot.preOrder();        } else {            System.out.println("此树为空, 无法完成前序遍历!");        }    }}class Node implements Comparable {    private int element; //节点的权    private Node left; //节点的左子树    private Node right; //节点的右子树    //构造器    public Node(int aElement) {        this.element = aElement;    }    public int getElement() {        return element;    }    public void setElement(int element) {        this.element = element;    }    public Node getLeft() {        return left;    }    public void setLeft(Node left) {        this.left = left;    }    public Node getRight() {        return right;    }    public void setRight(Node right) {        this.right = right;    }    //前序遍历    public void preOrder() {        System.out.print(this + " ");        if (this.getLeft() != null) {            this.getLeft().preOrder();        }        if (this.getRight() != null) {            this.getRight().preOrder();        }    }    @Override    public String toString() {        return element + "";    }    @Override    public int compareTo(Node o) {        return this.getElement() - o.getElement(); //从小大到排序    }}

最后我们采用前序遍历输出我们创建的赫夫曼树,结果如下

关于Java怎样实现赫夫曼树的创建就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

节点 结点 路径 森林 长度 赫夫 赫夫曼 子树 从小 哈夫 哈夫曼 叶子 树根 排序 最小 两个 之间 步骤 从小到大 之和 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技公司经营范围 美国互联网保险保险科技 平安科技 互联网 浩特互联网科技 互联网金融科技创新 米客互联网科技 深圳期待互联网科技 互联网养老 桔豆科技 镁科技互联网资讯平台 甘肃拓世互联网科技有限公司 无锡溥仪互联网科技有限公司 华脉科技工业互联网产品 海南科技产业互联网平台 上海电发互联网科技有限公司 群盈汇互联网科技有限公司 美国互联网科技实力 福建互联网展示科技馆设计 广州三三互联网科技有限公司 上海互联网科技园景观 北京瑞云互联网科技有限公司 互联网科技企业 互联网科技媒体 壕鑫互联网络科技 金融科技和互联网金融 深圳卡尔迅互联网科技有限公司怎么样 湖南诚度互联网科技有限公司 互联网科技创新服务 中国互联网有什么科技 半导体行业属于互联网高科技类吗 株洲百竞科技的互联网营销顾问
0