java哈夫曼编码详解

【说明】:核心思想在于哈夫曼树的构建、哈夫曼编码的输出、结点的定义(我个人将测试单独放在一个类中,这样主方法更加的轻捷,建议这样使用)。同时将将类放在一个包中。如下:
在这里插入图片描述
1.TreeNode.java(树的结点定义)

package com.yang.huffman;

/**
 * 哈夫曼树结点定义
 */
public class TreeNode {
    // 数据域
    private String data;
    // 权重
    private int weight;
    // 左孩子树
    private TreeNode left;
    // 右孩子树
    private TreeNode right;
    
    public TreeNode(String data, int weight) {
        this.data = data;
        this.weight = weight;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }

    public TreeNode getLeft() {
        return left;
    }

    public void setLeft(TreeNode left) {
        this.left = left;
    }

    public TreeNode getRight() {
        return right;
    }

    public void setRight(TreeNode right) {
        this.right = right;
    }

    @Override
    public String toString() {
        return "TreeNode{" +
                "data='" + data + '\'' +
                ", weight=" + weight +
                ", left=" + left +
                ", right=" + right +
                '}';
    }
}

2.HuffManTree.java(哈夫曼树的构建)

package com.yang.huffman;

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

/**
 * 哈夫曼树的构建
 */
public class HuffManTree {

    /**
     * 哈夫曼树的构建方法
     * @param treeNodes:存放结点的List集合
     * @return 哈夫曼树构建完成的根节点
     */
    public static TreeNode buildHuffManTree(List<TreeNode> treeNodes){

        // 判断树是否为空
        if (treeNodes.size()==0){
            return null;
        }

        // 循环构建树,先将所有的结点排序,然后利用贪心法构建,最后返回跟结点
        while (treeNodes.size()>1){
            // 将结点逆序排序
            reverse(treeNodes);
            // 构建左节点
            TreeNode left=treeNodes.get(treeNodes.size()-1);
            // 构建右结点
            TreeNode right=treeNodes.get(treeNodes.size()-2);
            // 得出前面两个结点的父亲结点
            TreeNode parent=new TreeNode(null,left.getWeight()+right.getWeight());
            parent.setLeft(left);
            parent.setRight(right);
            // 删除List集合中的用过的两个结点
            treeNodes.remove(left);
            treeNodes.remove(right);
            // 将生成的父亲结点放入到List集合中去
            treeNodes.add(parent);
        }
        for (TreeNode treeNode:treeNodes){
            System.out.println(treeNode);
        }
        return treeNodes.get(0);
    }

    /**
     * 对List集合中结点,按照权值的大小排序(逆序)
     */
    public static void reverse(List<TreeNode> treeNodes){

        int n=treeNodes.size();
        for(int i=n-1;i>0;i--){
            for(int j=0;j<=i-1;j++){
                if(treeNodes.get(j).getWeight()<=treeNodes.get(j+1).getWeight()){
                    TreeNode temp=treeNodes.get(j);
                    treeNodes.set(j,treeNodes.get(j+1));
                    treeNodes.set(j+1,temp);
                }
            }
        }
    }
}

3.HuffManCode.java(哈夫曼编码的得到)

package com.yang.huffman;

/**
 * 得到叶子结点的哈夫曼编码:由于在定义结点的时候加入了一个code的成员变量,记录了每一个结点的一个编码(0或者1)
 * 只要遍历哈夫曼树,得到每一个结点的对应的那个字符,然后拼接起来及可以得到叶子结点的编码
 */
public class HuffManCode {

    /**
     * 先序遍哈夫曼树得到叶子结点的哈夫曼编码
     * @param rootNode:根节点
     */
    public static void getHuffManCode(TreeNode rootNode,String huffManCode){

            if (rootNode.getData()!=null){
                System.out.print("数据:"+rootNode.getData()+"  "+"哈夫曼编码:"+huffManCode);
                System.out.println();
                return;
            }
            getHuffManCode(rootNode.getLeft(),huffManCode+"0");
            getHuffManCode(rootNode.getRight(),huffManCode+"1");
            return;
        }

}

4.HuffManTest.java(测试)

package com.yang.huffman;

import com.yang.traverse.BinaryTree;

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

/**
 * 哈夫曼树的测试
 */
public class HuffManTest {

    public static void main(String[] args) {

        List<TreeNode> treeNodes=new ArrayList<TreeNode>();
        treeNodes.add(new TreeNode("A",3));
        treeNodes.add(new TreeNode("B",1));
        treeNodes.add(new TreeNode("C",6));
        treeNodes.add(new TreeNode("D",4));
        TreeNode root=HuffManTree.buildHuffManTree(treeNodes);
        HuffManCode.getHuffManCode(root,"");
    }
}

【结果】:
在这里插入图片描述

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值