Creation of Huffman numbers and Huffman coding

Huffman Tree:

package Tree;

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

public class HuffmanTree {
    public static void main(String[] args) {

        int[] arr = {13, 7, 8, 3, 29, 6, 1};
        Node root = createHuffmanTree(arr);
        preOrder(root);
    }

    //Write a preorder traversal method
    public static void preOrder(Node root) {
        if (root != null) {
            root.preOrder();
        } else {
            System.out.println("It is an empty tree and cannot be traversed");
        }
    }

    //Method to create Huffman numbers
    public static Node createHuffmanTree(int[] arr) {
        //1. Traverse the arr array
        //2. Construct each element of arr into a Node
        //3. Put Node into ArrayList
        List<Node> nodes = new ArrayList<Node>();
        for (int value : arr) {
            nodes.add(new Node(value));
        }

        while (nodes.size() > 1) {

            Collections.sort(nodes);
            System.out.println("node=" + nodes);
            //Get the two binary trees with the smallest root nodes
            //1 Take the smallest node
            Node leftNode = nodes.get(0);
            //Get the next smallest node
            Node rightNode = nodes.get(1);

            //Construct a new binary tree
            Node parent = new Node(leftNode.value + rightNode.value);
            parent.left = leftNode;
            parent.right = rightNode;

            //Delete the processed binary tree from ArrayList
            nodes.remove(leftNode);
            nodes.remove(rightNode);
            //Add parent to nodes
            nodes.add(parent);
        }
        return nodes.get(0);
    }
}

//Create node class
class Node implements Comparable<Node> {
    int value;//node weight
    Node left;//points to the left child node
    Node right;//points to the right child node

    //Write a preorder traversal
    public void preOrder() {
        System.out.println(this);
        if (this.left != null) {
            this.left.preOrder();
        }
        if (this.right != null) {
            this.right.preOrder();
        }
    }

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

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

    @Override
    public int compareTo(Node o) {
        return this.value - o.value;//Sort from small to large
    }
}

Huffman coding:

Detailed explanation of ideas:

Code actual

package Tree;

import java.util.*;

public class HuffmanCode {
    public static void main(String[] args) {
        String content = "i like like like java do you like a java";
        byte[] contentBytes = content.getBytes();
        System.out.println(contentBytes.length);//40

        List<Node> nodes = getNodes(contentBytes);
        System.out.println("nodes=" + nodes);

        System.out.println("Huffman Tree");
        Node huffmanTreeRoot = createHuffmanTree(nodes);
        System.out.println("Preorder traversal");
        huffmanTreeRoot.preOrder();

        Map<Byte, String> huffmanCodes = getCodes(huffmanTreeRoot);
        System.out.println("Generated Huffman coding table" + huffmanCodes);
    }
    //Generate the Huffman code corresponding to the Huffman tree
    //1. Place the Huffman coding table in the form of Map<Byte, String> 32--01 97--100 100--11000
    static Map<Byte,String> huffmanCodes=new HashMap<Byte,String>();
    //2. When generating Huffman coding to represent the need to splice the path, define a StringBuilder to store the path of a certain leaf node.
    static StringBuilder stringBuilder=new StringBuilder();

    //Encapsulate a handful
    private static Map<Byte,String> getCodes(Node root){
        if(root==null){
            return null;
        }
        //Process the left subtree of root
        getCodes(root.left,"0",stringBuilder);
        getCodes(root.right,"1",stringBuilder);
        return huffmanCodes;
    }

    private static void getCodes(Node node,String code,StringBuilder stringBuilder){
        StringBuilder stringBuilder2=new StringBuilder(stringBuilder);
        //Add code to stringBuilder2
        stringBuilder2.append(code);
        if (node!=null){//If node==null is not processed
            //Determine whether the current node is a leaf node or a non-leaf node
            if(node.data==null){//Non-leaf node
                getCodes(node.left,"0",stringBuilder2);
                getCodes(node.right,"1",stringBuilder2);
            }else {//Indicates that it is a leaf node
                huffmanCodes.put(node.data, stringBuilder2.toString());
            }
        }
    }

    //preorder traversal
    private static void preOrder(Node root){
        if (root!=null){
            root.preOrder();
        }else {
            System.out.println("Huffman tree is empty");
        }
    }

    private static List<Node> getNodes(byte[] bytes) {
        ArrayList<Node> nodes = new ArrayList<>();
        Map<Byte, Integer> counts = new HashMap<>();
        for (byte b : bytes) {
            Integer count = counts.get(b);
            if (count == null) {
                counts.put(b, 1);
            } else {
                counts.put(b, count + 1);
            }
        }
        for (Map.Entry<Byte, Integer> entry : counts.entrySet()) {
            nodes.add(new Node(entry.getKey(), entry.getValue()));
        }
        return nodes;
    }

    //Create Huffman tree
    private static Node createHuffmanTree(List<Node> nodes) {
        while (nodes.size() > 1) {
            Collections.sort(nodes);
            Node leftNode = nodes.get(0);
            Node rightNode = nodes.get(1);
            //Create a binary tree whose root node only has weights and no date.
            Node parent = new Node(null, leftNode.weight + rightNode.weight);
            parent.left = leftNode;
            parent.right = rightNode;
            nodes.remove(leftNode);
            nodes.remove(rightNode);
            nodes.add(parent);
        }
        return nodes.get(0);
    }
}

//Create Node to store data and weights
class Node implements Comparable<Node> {
    Byte data;
    int weight;
    Node left;
    Node right;

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

    @Override
    public int compareTo(Node o) {
        return this.weight - o.weight;
    }

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

    //preorder traversal
    public void preOrder() {
        System.out.println(this);
        if (this.left != null) {
            this.left.preOrder();
        }
        if (this.right != null) {
            this.right.preOrder();
        }
    }
}

Now: