华为OD机考-生成哈夫曼树-二叉树(JAVA 2025B卷)


java 复制代码
import java.util.*;

 class HuffmanNode implements Comparable<HuffmanNode> {
    int weight;
    HuffmanNode left, right;

    HuffmanNode(int weight) {
        this.weight = weight;
        this.left = this.right = null;
    }

    @Override
    public int compareTo(HuffmanNode other) {
        return this.weight - other.weight;
    }
}

public class HuffmanTree {
    /**
     * 构建哈夫曼树
     * 哈夫曼树是一种带权路径长度最短的二叉树,也称为最优二叉树
     * 在数据压缩、编码等领域有广泛的应用
     *
     * @param weights 每个节点的权重,权重越小的节点,在构建哈夫曼树时,越靠近根节点
     * @return 返回哈夫曼树的根节点
     */
    public static HuffmanNode buildHuffmanTree(int[] weights) {
        // 优先队列,用于存储哈夫曼树的节点,队列头部元素权值最小
        PriorityQueue<HuffmanNode> pq = new PriorityQueue<>();

        // 遍历所有节点权重,初始化哈夫曼树节点并加入优先队列
        for (int weight : weights) {
            pq.add(new HuffmanNode(weight));
        }

        // 当优先队列中节点数量大于1时,循环构建哈夫曼树
        while (pq.size() > 1) {
            // 从优先队列中取出权值最小的两个节点
            HuffmanNode left = pq.poll();
            HuffmanNode right = pq.poll();

            // 断言right节点非空,确保树能正常构建
            assert right != null;
            // 创建新的哈夫曼节点,作为left和right节点的父节点,其权重为两个子节点权重之和
            HuffmanNode parent = new HuffmanNode(left.weight + right.weight);

            // 设置父节点的左右子节点
            parent.left = left;
            parent.right = right;

            // 将新的父节点加入优先队列
            pq.add(parent);
        }

        // 返回优先队列中剩余的唯一节点,即哈夫曼树的根节点
        return pq.poll();
    }


    /**
     * 中序遍历哈夫曼树
     * 中序遍历的特点是左子树-根节点-右子树的顺序访问树中的节点
     * 这种遍历顺序在哈夫曼树中主要用于验证树的结构,而不用于构建最短编码
     *
     * @param root 哈夫曼树的根节点
     * @param result 用于存储遍历结果的列表,通常是节点的权重
     */
    public static void inorderTraversal(HuffmanNode root, List<Integer> result) {
        // 判断当前节点是否为空,为空则直接返回
        if (root == null) {
            return;
        }

        // 递归中序遍历左子树
        inorderTraversal(root.left, result);

        // 将当前节点的权重添加到结果列表中
        result.add(root.weight);

        // 递归中序遍历右子树
        inorderTraversal(root.right, result);
    }


    /**
     * 主函数入口
     * 本程序用于演示霍夫曼树的构建及其遍历过程
     * 霍夫曼树是一种带权路径长度最短的二叉树,具有重要应用价值
     *
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        // 创建Scanner对象,用于读取命令行输入
        Scanner scanner = new Scanner(System.in);

        // 读取霍夫曼树节点数量
        int n = scanner.nextInt();
        // 初始化霍夫曼树节点权重数组
        int[] weights = new int[n];

        // 读取每个节点的权重
        for (int i = 0; i < n; i++) {
            weights[i] = scanner.nextInt();
        }

        // 构建霍夫曼树并返回根节点
        HuffmanNode root = buildHuffmanTree(weights);

        // 初始化用于存储中序遍历结果的列表
        List<Integer> result = new ArrayList<>();

        // 中序遍历霍夫曼树,并将结果存储到列表中
        inorderTraversal(root, result);

        // 输出中序遍历结果
        for (int weight : result) {
            System.out.print(weight + " ");
        }
    }
}
相关推荐
invicinble几秒前
关于springboot引入traceid来保障可观测型
java·spring boot·后端
爱装代码的小瓶子2 分钟前
【cpp进阶】c++11的新特性(概述版)
开发语言·c++
_OP_CHEN7 分钟前
【从零开始的Qt开发指南】(十一)Qt常用控件之多元素控件与容器类控件深度解析
开发语言·qt·前端开发·多元素控件·gui开发·qt常用控件·容器类控件
Robot侠7 分钟前
视觉语言导航从入门到精通(二)
开发语言·人工智能·python·llm·vln
SmoothSailingT9 分钟前
C#——Lazy<T>懒加载机制
开发语言·单例模式·c#·懒加载
精神病不行计算机不上班11 分钟前
[Java Web]在IDEA中完整实现Servlet的示例
java·servlet·tomcat·html·intellij-idea·web
chushiyunen12 分钟前
javadoc规范、idea生成javadoc等
java·ide
小羊学伽瓦16 分钟前
ThreadLocal
java·jvm·算法
程序喵大人17 分钟前
SQLITE问题整理
开发语言·数据库·c++·sqlite
Neolnfra18 分钟前
文件包含漏洞终极指南
开发语言·安全·web安全·网络安全·系统安全·php·可信计算技术