zoukankan      html  css  js  c++  java
  • 【数据结构与算法】10.1、赫夫曼树代码实现

    1、基本介绍

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

    2、实现思路

    构成赫夫曼树的步骤:
    1)从小到大进行排序,将每一个数据,每个数据都是一个节点,每个节点可以看成是一颗最简单的二叉树2)取出根节点权值最小的两颗二叉树
    3)组成一颗新的二又树,该新的二叉树的根节点的权值是前面两颗二又树根节点权值的和
    4)再将这颗新的二叉树,以根节点的权值大小再次排序,不断重复1-2-3-4的步骤,直到数列中,所有的数据都被处理,就得到一颗赫夫曼树

    3、代码实现

    package com.hblg.huffmantree;
    
    import org.jetbrains.annotations.NotNull;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.List;
    
    /**
     * @author i
     * @create 2019/10/17 19:27
     * @Description 赫夫曼树创建
     *
     * 主要实现思路:1.从小到达进行排序,将每一个数据,每个数据都是一个节点,每个节点都可以看成是一颗最简单的二叉树,
     * 2.取出根节点权值最小的两颗二叉树。
     * 3.组成一课新的二叉树,该树的二叉树的根节点的权值是前面两颗二叉树的根节点权值的值
     * 4.在将这颗新的二叉树,以根节点的权值大小 在此排序,不断重复 直至数列中,所有的数据被处理,就得到了一颗赫夫曼树。
     */
    public class HuffmanTree {
    
        public static void main(String[] args) {
            HuffmanTree huffmanTree = new HuffmanTree();
            int[] array = {13, 7, 8, 1};
            Node rootNode = createHuffmanTree(array);
            preHuffmanTree(rootNode);
        }
    
        /***
         * 遍历赫夫曼树 - 前序遍历
         * @param rootNode
         */
        public static void preHuffmanTree(Node rootNode) {
            if (rootNode != null) {
                rootNode.preOrder();
            } else {
                System.out.println("空树!");
            }
        }
    
        //创建赫夫曼树
        public static Node createHuffmanTree(int[] array) {
            //数组转换成指定的赫夫曼树
            List<Node> nodes = new ArrayList<>();
            //遍历 将数组中的值添加到集合中
            for (Integer value : array) {
                nodes.add(new Node(value));
            }
    
            while (nodes.size() > 1) {
    
                //将集合中的元素,进行排序 从小到大
                Collections.sort(nodes);
    
                System.out.println(nodes);
    
                //获取最小权值的数
                Node leftNode = nodes.get(0);
                //获取次小权值的数
                Node rightNode = nodes.get(1);
    
                //添加新的节点 最小权值和次小权值的总数和
                Node parentNode = new Node(leftNode.getValue() + rightNode.getValue());
                parentNode.leftNode = leftNode;
                parentNode.rightNode = rightNode;
    
                //删除 最小权值节点 和 次小权值的节点
                nodes.remove(leftNode);
                nodes.remove(rightNode);
                //添加到父节点上
                nodes.add(parentNode);
            }
            return nodes.get(0);
        }
    
    
    }
    
    //创建一个节点
    class Node implements Comparable {
        private Integer value;
        public Node leftNode;
        public Node rightNode;
    
        public Node() {
        }
    
        public Node(Integer value) {
            this.value = value;
        }
    
        public Node(Integer value, Node leftNode, Node rightNode) {
            this.value = value;
            this.leftNode = leftNode;
            this.rightNode = rightNode;
        }
    
        /***
         * 前序遍历
         */
        public void preOrder() {
            System.out.println(this);
            if (this.leftNode != null) {
                this.leftNode.preOrder();
            }
            if (this.rightNode != null) {
                this.rightNode.preOrder();
            }
        }
    
        public Integer getValue() {
            return value;
        }
    
        public void setValue(Integer value) {
            this.value = value;
        }
    
        @Override
        public String toString() {
            return "Node{" +
                    "value=" + value +
                    '}';
        }
    
        //比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
        @Override
        public int compareTo(@NotNull Object o) {
            return this.value - ((Node) o).value;
        }
    }
    
  • 相关阅读:
    【转】自旋锁及其衍生锁
    【转】 android 4.4 Step Counter Sensor计步器的使用
    【转】ListView与RadioButton组合——自定义单选列表
    【转】带checkbox的ListView实现(二)——自定义Checkable控件的实现方法
    【转】Android 带checkbox的listView 实现多选,全选,反选 -- 不错
    【转】linux 原子整数操作详解
    计算机科学界名言
    计算机科学界名言
    益智小游戏(app)
    益智小游戏(app)
  • 原文地址:https://www.cnblogs.com/qxlxi/p/12860786.html
Copyright © 2011-2022 走看看