Huffman树

178 阅读1分钟
  • 简介
给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,
也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
  • 例子
对于这样一个数组:int[] arr = {13, 7, 8, 3, 29, 6, 1};
构建Huffman树,首先要进行排序(从小到大)。

创建:
排序后的数组为:{1,3,6,7,8,13,29}
step1:取出其中最小的两个值1,3,将其构建成一棵树。将这两个值,从数组中删除,并将其和加入到原数组,
且重新进行排序。
循环step1,直到整个数组剩下最后一个节点,即root节点。

Huffman创建步骤

  • 代码
package tree;

import java.util.ArrayList;
import java.util.Arrays;
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};
        HuffmanTreeNode root = createHuffmanTree(arr);

        preOrder(root);
    }

    //创建huffman树
    public static HuffmanTreeNode createHuffmanTree(int[] arr) {
        //使用list,方便删除和添加
        List<HuffmanTreeNode> list = new ArrayList<>();

        for (int i : arr) {
            list.add(new HuffmanTreeNode(i));
        }

        while (list.size()>1) {
            //排序,从小到大
            Collections.sort(list);

            //取出根节点权值最小的两棵二叉树
            HuffmanTreeNode left = list.get(0);
            //第二小
            HuffmanTreeNode right = list.get(1);

            HuffmanTreeNode parent = new HuffmanTreeNode(left.data + right.data);
            parent.left = left;
            parent.right = right;

            //从list中删除处理过的二叉树
            list.remove(left);
            list.remove(right);

            //将parent加入list,下一步,重新排序
            list.add(parent);

        }
        //返回root节点
        return list.get(0);
    }

    //前序遍历
    public static void preOrder(HuffmanTreeNode parent){
        if (parent != null){
            parent.preOrder();
        }else
            System.out.println("空树");
    }
}

class HuffmanTreeNode implements Comparable<HuffmanTreeNode> {
    public int data;
    HuffmanTreeNode right;
    HuffmanTreeNode left;

    public HuffmanTreeNode(int data) {
        this.data = data;
    }

    //前序遍历
    public void preOrder(){
        System.out.println(this.data);
        if (this.left != null)
            this.left.preOrder();
        if (this.right != null)
            this.right.preOrder();

    }


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