java实现Haffman编码

1、先创建一个树节点类(泛型类),为了方便使用集合的排序方法,泛型类要实现泛型接口Comparable,代码如下

package com.hjp.huffman;

/**
 * Created by JiaPeng on 2016/12/28.
 */
public class Node<T> implements Comparable<Node<T>> {

    private T data;
    private int weight;
    private Node<T> left;
    private Node<T> right;
    private String codeStr;

    public T getData() {
        return data;
    }

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

    public int getWeight() {
        return weight;
    }

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

    public Node<T> getLeft() {
        return left;
    }

    public void setLeft(Node<T> left) {
        this.left = left;
    }

    public Node<T> getRight() {
        return right;
    }

    public void setRight(Node<T> right) {
        this.right = right;
    }

    public Node(T data, int weight) {
        this.data = data;
        this.weight = weight;
    }

    public String getCodeStr() {
        return codeStr;
    }

    public void setCodeStr(String codeStr) {
        this.codeStr = codeStr;
    }

    @Override
    public int compareTo(Node<T> o) {
        if (o.weight > this.weight) {
            return 1;
        } else if (o.weight < this.weight) {
            return -1;
        }
        return 0;
    }

    @Override
    public String toString() {
        return "data:" + this.data + ",weight:" + this.weight + "; ";
    }
}

树节点类

2、编写泛型静态方法,构造Haffman树及对树编码,代码如下

package com.hjp.huffman;

import java.util.*;

/**
 * Created by JiaPeng on 2016/12/28.
 */
public class HuffmanTree {

    public static <T> Node<T> createTree(List<Node<T>> nodes) {
        while (nodes.size() > 1) {
            int nodesLen = nodes.size();
            Collections.sort(nodes);
            Node<T> left = nodes.get(nodesLen - 1);
            Node<T> right = nodes.get(nodesLen - 2);
            Node<T> parent = new Node<T>(null, left.getWeight() + right.getWeight());
            parent.setLeft(left);
            parent.setRight(right);
            nodes.remove(left);
            nodes.remove(right);
            nodes.add(parent);
        }
        return nodes.get(0);
    }

    public static <T> List<Node<T>> breath(Node<T> root) {
        List<Node<T>> list = new ArrayList<Node<T>>();
        Queue<Node<T>> queue = new LinkedList<Node<T>>();
        queue.add(root);
        StringBuilder stringBuilder = new StringBuilder();
        while (!queue.isEmpty()) {
            Node<T> pNode = queue.poll();
            list.add(pNode);
            Node<T> leftNode = pNode.getLeft();
            String codeStr = pNode.getCodeStr();
            if (leftNode != null) {
                if (codeStr != null && !"".equals(codeStr)) {
                    leftNode.setCodeStr(codeStr + "0");
                } else {
                    leftNode.setCodeStr("0");
                }
                queue.add(leftNode);
            }
            Node<T> rightNode = pNode.getRight();
            if (rightNode != null) {
                if (codeStr != null && !"".equals(codeStr)) {
                    rightNode.setCodeStr(codeStr + "1");
                } else {
                    rightNode.setCodeStr("1");
                }
                queue.add(rightNode);
            }
        }
        return list;
    }

}

构造树方法及编码方法

3、测试方法

package com.hjp.huffman;

import com.hjp.data.JSONUtil;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by JiaPeng on 2016/12/28.
 */
public class testMain {

    public static void main(String[] args){
        List<Node<String>> nodes = new ArrayList<Node<String>>();
        nodes.add(new Node<String>("b", 5));
        nodes.add(new Node<String>("a", 7));
        nodes.add(new Node<String>("d", 2));
        nodes.add(new Node<String>("c", 4));
        Node<String> root = HuffmanTree.createTree(nodes);
        List<Node<String>> huffmanList=HuffmanTree.breath(root);
        Map<String,String> huffmanMap=new LinkedHashMap<String, String>();
        for (int i = 0; i < huffmanList.size(); i++) {
            Node<String> curNode=huffmanList.get(i);
            if(curNode.getData()!=null){
                huffmanMap.put(curNode.getData(),curNode.getCodeStr());
            }
        }
        System.out.println(JSONUtil.toJson(huffmanMap));
    }

}

测试方法

时间: 2024-10-19 03:38:29

java实现Haffman编码的相关文章

Java与编码问题串讲之二–如何理解java采用Unicode编码

Java开发者必须牢记:在Java中字符仅以一种形式存在,那就是Unicode(不选择任何特定的编码,直接使用他们在字符集中的编号,这是统一的唯一方法).由于java采用unicode编码,char 在java中占2个字节.2个字节(16位)来表示一个字符. 这里的Java中是指在JVM中.在内存中.在代码里声明的每一个char.String类型的变量中. 例如: 1 2 3 4 5 6 7 System.out.println(System.getProperty("file.encoding

java语言字符编码问题

上代码 import java.io.*; public class EncodingDemo { public static void main(String[] args) { System.getProperties().list(System.out); try { FileWriter fw=new FileWriter("F:\\workspace\\JavaPrj\\test.txt"); fw.write("小超是个好孩子!"); fw.close(

windows下编译java源文件的编码错误

import java.util.Arrays;public class ArrayAsAReference{ public static void main(String[] args) { int[] arr = null; System.out.println(arr); arr = new int[]{1, 2, 3, 4}; // 静态创建数组对象 System.out.println(Arrays.toString(arr)); int[] prices; prices = new

Java 中需要编码的场景

I/O 操作中存在的编码 我们知道涉及到编码的地方一般都在字符到字节或者字节到字符的转换上,而需要这种转换的场景主要是在 I/O 的时候,这个 I/O 包括磁盘 I/O 和网络 I/O,关于网络 I/O 部分在后面将主要以 Web 应用为例介绍.下图是 Java 中处理 I/O 问题的接口: Reader 类是 Java 的 I/O 中读字符的父类,而 InputStream 类是读字节的父类,InputStreamReader 类就是关联字节到字符的桥梁,它负责在 I/O 过程中处理读取字节到

java利用Base64编码和解码图片文件

1.编码与解码代码如下所示: import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import javax.image

java良好的编码习惯

1. 尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时间,提高加载的效率,但并不是所有地方都适用于单例,简单来说,单例主要适用于以下三个方面: 第一,控制资源的使用,通过线程同步来控制资源的并发访问: 第二,控制实例的产生,以达到节约资源的目的: 第三,控制数据共享,在不建立直接关联的条件下,让多个不相关的进程或线程之间实现通信. 2. 尽量避免随意使用静态变量 要知道,当某个对象被定义为stataic变量所引用,那么gc通常是不会回收这个对象所占有的内存,如 Java代码 p

关于java中的编码问题

GET方式提交的数据不会受页面编码的影响,应该都是以iso8859-1方式编码提交到后台程序,在后台java代码中可以通过 String str1=new String(name.getBytes("iso8859-1"),"UTF-8"); 的方式对字符串解码,解决乱码问题. 关于java中的编码问题,布布扣,bubuko.com

Delphi和JAVA用UTF-8编码进行Socket通信例子

最近的项目(Delphi开发),需要经常和java语言开发的系统进行数据交互(Socket通信方式),数据编码约定采用UTF-8编码. 令我无语的是:JAVA系统那边反映说,Delphi发的数据他们收到是乱码,而我这边(Delphi7,ANSI)收到的数据将utf-8转码成ansi也是乱码. 因为不太熟悉java语言,还曾经怀疑是不是Delphi的utf-8编码和java语言的不一样. 最近学习了一下java的相关知识,写一个小程序来测试验证一下我曾经的怀疑. 事实证明,Delphi7的UTF-

java中的编码问题

一直在试图搞清楚java中的编码问题,也看了网上的一些文章,但还是云里雾里.直到最近看了方立勋老师的web课程,才略略明白一点. 在此记录一下自己的理解,看看自己能不能说清楚. 第一个问题:我在java代码中定义了一个字符串,它是什么编码? 字符串实质是一个char数组.那么char的编码,其实就是字符串的编码.那么char什么编码呢?为什么'中'字转int类型后的值是20013呢? char c = '中'; System.out.println(c); // 中 System.out.pri