Introducción al árbol de Huffman e implementación de Java

1. Introducción

1.1 árbol de Huffman

  • Árbol binario óptimo del árbol de Huffman: el árbol binario con la longitud de ruta ponderada más pequeña del árbol;
  • Los pesos son todos nodos de hojas;
  • Cuanto mayor sea el peso, más cerca estará el nodo del nodo raíz;

inserte la descripción de la imagen aquí

1.2 Ruta, longitud de ruta, peso de nodo, longitud de ruta ponderada por nodo

inserte la descripción de la imagen aquí

1.3 La longitud de ruta ponderada WPL del árbol

inserte la descripción de la imagen aquí

2. Pasos para la construcción del árbol Huffman

  • Organice la secuencia de pesos en orden ascendente y seleccione los dos pesos más pequeños para fusionar;
  • Agregue los nodos fusionados a la secuencia de pesos y reordenelos;
  • Repita las dos operaciones anteriores hasta que solo quede un nodo en la secuencia para completar la creación;
    inserte la descripción de la imagen aquí
  • Resultados de compilación manual para el caso anterior:
    inserte la descripción de la imagen aquí

3. Implementación del código

package com.northsmile.tree.huffman;

import java.util.*;

/**
 * @author NorthSmile
 * @version 1.0
 * @date 2023/8/21&18:36
 * 哈夫曼树实现
 */
public class HuffmanTree {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner=new Scanner(System.in);
        int n=Integer.parseInt(scanner.nextLine());
        List<TreeNode> nodes=new LinkedList<>();
        for (int i=0;i<n;i++){
    
    
            nodes.add(new TreeNode(Integer.parseInt(scanner.nextLine())));
        }
        root=createHuffmanTree(nodes);
        // System.out.println(root.val);
        System.out.println(calWPL());
    }
    // 根节点
    private static TreeNode root;

    // 构建哈夫曼树
    public static TreeNode createHuffmanTree(List<TreeNode> nodes){
    
    
        while (nodes.size()!=1){
    
    
            // 升序排列
            nodes.sort(new Comparator<TreeNode>() {
    
    
                @Override
                public int compare(TreeNode o1, TreeNode o2) {
    
    
                    return o1.val-o2.val;
                }
            });
            // 合并两个最小节点
            TreeNode left=nodes.get(0);
            TreeNode right=nodes.get(1);
            // System.out.println(left.val+" "+right.val);
            TreeNode curRoot = new TreeNode(left.val+right.val);
            curRoot.left=left;
            curRoot.right=right;
            nodes.add(curRoot);
            // 删除两个最小节点
            nodes.remove(0);
            nodes.remove(0);
        }
        return nodes.get(0);
    }

    // 计算WPL
    // 层序遍历
    public static int calWPL(){
    
    
        int wpl=0;
        Deque<TreeNode> queue=new ArrayDeque<>();
        queue.offer(root);
        int height=0;
        while (!queue.isEmpty()){
    
    
            int size=queue.size();
            for (int i=0;i<size;i++){
    
    
                TreeNode cur = queue.pop();
                if (cur.left==null&&cur.right==null){
    
    
                    wpl+=(cur.val*height);
                }
                if (cur.left!=null){
    
    
                    queue.offer(cur.left);
                }
                if (cur.right!=null){
    
    
                    queue.offer(cur.right);
                }
            }
            height++;
        }
        return wpl;
    }

    // 树节点
    private static class TreeNode{
    
    
        public int val;
        public TreeNode left;
        public TreeNode right;

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

Supongo que te gusta

Origin blog.csdn.net/qq_43665602/article/details/132413037
Recomendado
Clasificación