死磕数据结构与算法——哈夫曼树(java实现)。才疏学浅,如有错误,及时指正

死磕数据结构与算法——哈夫曼树(java实现)。才疏学浅,如有错误,及时指

1. 基本概念

哈夫曼树:给定n个权值作为n个叶子节点,构造一棵二叉树,若该数的带权路径长度达到最小,这样的二叉树称为最优二叉树,也叫做哈夫曼树(Huffman Tree)。哈夫曼树是一个带权路径长度最短的树,其中权值越大的节点离根节点越近。
路径:在一棵树中,从一个节点往下可以到达的孩子或孙子节点之间的通路,称为路径。
路径长度:通路中分支的数组称为路径长度。若规定根节点的层数为1,则从根节点到第N层节点的路径长度为N-1.
节点的权:若将数中节点赋给一个某种含义的数值,则这个数值成为节点的权。
节点的带权路径长度:从根节点到该节点之间的路径长度与该节点权的乘积。
即:带权路径长度 = 路径长度 * 该节点权
树的带权路径长度:所有叶子节点的带权路径长度之和。记为WPL。
哈夫曼树:带权路径长度最小的就是哈夫曼树。即WPL最小。

示例:
在这里插入图片描述
wpl: 13 * 1 + 8 * 2 + 7 * 3 + 3 * 3 = 59

2. 步骤

把一个数组构建称哈夫曼树的步骤

  1. 把数组从小到大进行排序,每个数据都是一个节点,每个节点都可以看成一个最简单的二叉树。
  2. 取出根节点权最小的两棵二叉树。
  3. 组成一棵新的二叉树,该树的根节点为去出的两棵二叉树的权值和。
  4. 将这棵新的二叉树,以根节点的权值进行大小排序。然后把这个新的二叉树的根节点放入数组中。重复1234的步骤,直到数组中只剩下一个树的时候,所有的数据都被处理。这时就得到了一棵哈夫曼树。

3. 示例代码

package HafmTree;

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

public class HafumanTree {
    
    
    public static void main(String[] args) {
    
    
        int[] arr = {
    
    13, 7, 8, 3, 29, 6, 1};
        NodeTree root = createHafmanTree( arr );

        //测试
        preOrder( root );

    }

    //编写一个前序遍历的方法
    public static void preOrder(NodeTree root) {
    
    
        if(root != null){
    
    
            root.preOreder();
        }else {
    
    
            System.out.println("是空树,不能遍历");
        }
    }

    public static NodeTree createHafmanTree (int[] arr){
    
    
        //1. 把数组中的每一个值都创建成一个NodeTree节点
        List<NodeTree> nodes = new ArrayList<NodeTree>(  );
        for(int value : arr){
    
    
            nodes.add(new NodeTree( value ));
        }
        while(nodes.size() > 1){
    
    
            //2. 从小到大进行排序
            Collections.sort( nodes );

            //3. 取出根节点权值最小的两棵二叉树
            NodeTree leftNode = nodes.get( 0 );
            NodeTree rightNode = nodes.get( 1 );

            //4. 构建一棵新的二叉树
            NodeTree parent = new NodeTree( leftNode.value + rightNode.value );
            parent.left = leftNode;
            parent.right = rightNode;

            //5. 从nodes中删除处理过的节点
            nodes.remove( 1 );
            nodes.remove( 0 );
            nodes.add( parent );
        }

        //返回哈夫曼树的root节点
        return nodes.get( 0 );

    }
}
//定义树的结构
class NodeTree implements Comparable<NodeTree> {
    
    
    int value; //权值
    NodeTree left;  //指向左节点
    NodeTree right;  //指向右节点
    public NodeTree (int value){
    
    
        this.value = value;
    }

    //前序遍历二叉树
    public void preOreder() {
    
    
        System.out.println(this);
        if(this.left != null){
    
    
            this.left.preOreder();
        }
        if(this.right != null){
    
    
            this.right.preOreder();
        }
    }

    public String toString() {
    
    
        return "TreeNode [value=" + value + "]";
    }

    @Override
    public int compareTo(NodeTree o) {
    
    
        return this.value - o.value;
    }
}


总结:

本文使用java完成了一个最简单的哈夫曼树。哈夫曼树还有很多实际的应用,比如编码表的压缩等

猜你喜欢

转载自blog.csdn.net/qq_41497756/article/details/109254519
今日推荐