• 赫夫曼树


    一、基本介绍

      1、给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度(wpl)达到最小,称这  样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree), 还有的书翻译为霍夫曼树。

      2、赫夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

    二、重要概念

      1、路径和路径长度:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1
      2、结点的权及带权路径长度:若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积
      3、树的带权路径长度:树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL(weighted path length) ,权值越大的结点离根结点越近的二叉树才是最优二叉树。
      4、WPL最小的就是赫夫曼树
      

    三、代码

      

     1 public class HuffmanTree {
     2 
     3     public static void main(String[] args) {
     4         int arr[] = { 13, 7, 8, 3, 29, 6, 1 };
     5         Node root = createHuffmanTree(arr);
     6 
     7         preOrder(root);
     8     }
     9     public static  void preOrder(Node root){
    10         if(root!=null){
    11             root.preOrder();
    12         }else {
    13             System.out.println("空数");
    14         }
    15     }
    16 
    17     // 创建赫夫曼树的方法
    18     /**
    19      * @param arr 需要创建成哈夫曼树的数组
    20      * @return 创建好后的赫夫曼树的root结点
    21      */
    22     public static Node createHuffmanTree(int[] arr){
    23         // 第一步为了操作方便
    24         // 1. 遍历 arr 数组
    25         // 2. 将arr的每个元素构成成一个Node
    26         // 3. 将Node 放入到ArrayList中
    27        ArrayList<Node> nodes = new ArrayList<>(arr.length);
    28         for (int v : arr) {
    29             nodes.add(new Node(v));
    30         }
    31         //我们处理的过程是一个循环的过程
    32         while (nodes.size()>1){
    33             //排序 从小到大
    34             Collections.sort(nodes);
    35             System.out.println(nodes);
    36             //取出根节点权值最小的两颗二叉树
    37             //(1) 取出权值最小的结点(二叉树)
    38             Node l = nodes.get(0);
    39             //(2) 取出权值第二小的结点(二叉树)
    40             Node r = nodes.get(1);
    41             //(3)构建一颗新的二叉树
    42             Node parent = new Node(l.value + r.value);
    43             parent.left = l;
    44             parent.right = r;
    45             //(4)从ArrayList删除处理过的二叉树
    46             nodes.remove(l);
    47             nodes.remove(r);
    48             //(5)将parent加入到nodes
    49             nodes.add(parent);
    50         }
    51         //返回哈夫曼树的root结点
    52         return nodes.get(0);
    53     }
    54 }
    55 // 创建结点类
    56 // 为了让Node 对象持续排序Collections集合排序
    57 // 让Node 实现Comparable接口
    58 class Node implements Comparable<Node>{
    59     int value;// 结点权值
    60     char c;
    61     Node left;
    62     Node right;
    63     //写一个前序遍历
    64     public void preOrder(){
    65         System.out.println(this);
    66         if(this.left!=null){
    67             this.left.preOrder();
    68         }
    69         if(this.right!=null){
    70             this.right.preOrder();
    71         }
    72     }
    73     @Override
    74     public String toString() {
    75         return "Node{" +
    76                 "value=" + value +
    77                 '}';
    78     }
    79 
    80     public Node(int value) {
    81         this.value = value;
    82     }
    83 
    84     @Override
    85     public int compareTo(Node o) {
    86         return 0;
    87     }
    88 }
  • 相关阅读:
    day18:正则表达式和re模块
    finance1:专业词汇
    Iterator & Iterable 和 Comparable&Comparator
    pandas中三种索引方式(.loc.iloc.ix)
    XML序列化与反序列化
    控件蓝图里控件绑定问题
    Mouse Properties(鼠标属性)
    cSV
    从父控件移除控件
    是否显示鼠标指针
  • 原文地址:https://www.cnblogs.com/hyunbar/p/11502783.html
Copyright © 2020-2023  润新知