粗陋的哈夫曼算法的实现

Huffman的概念:
以哈夫曼树─即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。 在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称“熵编码法”),用于数据的无损耗压缩。这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。这种方法是由David.A.Huffman发展起来的。 例如,在英文中,e的出现概率很高,而z的出现概率则最低。当利用哈夫曼编码对一篇英文进行压缩时,e极有可能用一个位(bit)来表示,而z则可能花去25个位(不是26)。用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个位。二者相比,e使用了一般编码的1/8的长度,z则使用了3倍多。倘若我们能实现对于英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。
[size=large][color=darkblue]1.Node.java[/color][/size]

package cn.com.Huffman;
/**
 * 二叉树的节点的实现
 * @author Administrator
 *2013.3.31
 */
public class Node {
	public String data;//保存的字符
	public int a; //字符个数
	public String huffmandata;//哈夫曼编码
	public Node leftchild; //左孩子
	public Node rightchild;//右孩子
	/**
	 * 构造器的实现
	 * @param data 字符
	 * @param a  data字符个数
	 */
	public Node(String data,int a){
		this.data = data;
		this.a = a;
		huffmandata = null;
		leftchild = null;
		rightchild = null;
	}
/**
 * 构造器的实现
 * @param a 字符的个数
 */
	public Node(int a){
		this.a = a;
	}
}




[size=large][color=darkblue]2.HuffmanCode.java[/color][/size]
package cn.com.Huffman;

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

/**
 * Huffman编码的实现
 * @author Administrator
 *2013.3.31
 */
public class HuffmanCode {
	private Node root; //根节点
	List<Node> list = new ArrayList<Node>();
	/**
	 * 默认构造器的实现
	 */
	public HuffmanCode(){
		root = null;
	}
	/**
	 * 实现Huffman编码
	 * @param node 传入的节点数组
	 */
	public void huffman(Node[] node){
		if(node.length==1){
			return;
		}
		if(node.length==2){
			int d = node[0].a+node[1].a;
			root = new Node(d);
			root.leftchild = node[0];
			addZeroLeftChild(node[0]);//实现节点内哈夫曼编码的加0
			root.rightchild = node[1];
			addOneRightChild(node[1]);//实现节点内哈夫曼编码的加1
			return;
		}
		int d = node[0].a+node[1].a;
		Node no = new Node(d);
		no.leftchild = node[0];
		addZeroLeftChild(node[0]);//实现节点内哈夫曼编码的加0
		no.rightchild = node[1];
		addOneRightChild(node[1]);//实现节点内哈夫曼编码的加1
		Node[] c = new Node[node.length-1];
		for(int i=0;i<c.length-1;i++){
			c[i] = node[i+2];
		}
		c[c.length-1] = no;
		huffman(sort(c));
	}
	/**
	 * 对节点数组进行排序
	 * @param a无序的节点数组
	 * @return 返回的是有序的节点数组
	 */
	public Node[] sort(Node[] a){
		for(int i=0;i<a.length;i++){
			for(int j=i;j<a.length;j++){
				if(a[i].a>a[j].a){
					Node b = a[i];
					a[i] = a[j];
					a[j] = b;
				}
			}
		}
		return a;
	}
	/**
	 * 子节点node作为右孩子,则它以及它的子节点对象中的Huffmancode前加1;
	 * @param node 孩子节点
	 */
	public void addOneRightChild(Node node){
		if(node!=null){
			node.huffmandata ="1"+ node.huffmandata;
			addOneRightChild(node.leftchild);
			addOneRightChild(node.rightchild);
		}
	}
	/**
	 * 子节点node作为左孩子,则它以及它的子节点对象中的Huffmancode前加0;
	 * @param node 孩子节点
	 */
	public void addZeroLeftChild(Node node){
		if(node!=null){
			node.huffmandata ="0"+ node.huffmandata;
			addZeroLeftChild(node.leftchild);
			addZeroLeftChild(node.rightchild);
		}
	}
	/**
	 * 可传入root根节点,在控制台输出字符的个数和Huffman编码
	 * @param node 
	 */
	public void get(Node node){
		
		if(node!=null){
			System.out.println(node.a+" ,"+node.huffmandata);
			get(node.leftchild);
			get(node.rightchild);
		}
	}
	/**
	 * 将字符串转换成Node节点数组
	 * @param str //传入的字符串
	 * @return 返回一个有序Node[]
	 */
	public Node[] formString(String str){
		char[] ch = str.toCharArray();
		
		for(int i=0;i<ch.length;i++){
			Node node = new Node(String.valueOf(ch[i]),0);
			list.add(node);
		}

		for(int i=0;i<ch.length;i++){
			int k = 0;
			Node no =null;
			for(int j=0;j<list.size();j++){
				if(String.valueOf(ch[i]).equals(list.get(j).data) && list.get(j).a==0){
					no = list.get(j);
					list.remove(j);
					k++;
				}
			}
			if(no!=null){
				no.a = k;
				list.add(no);
			}
		}
		Node[] n = new Node[list.size()];
		for(int i=0;i<n.length;i++){
			n[i] = list.get(i);
		}
		return n;
	}
	/**
	 * 主函数入口
	 * @param args
	 */
	public static void main(String args[]){
		HuffmanCode hc = new HuffmanCode();
		Node[] node = hc.formString("jiandequn");
		for(int i=0;i<hc.list.size();i++){
			System.out.println(hc.list.get(i).data+",  "+hc.list.get(i).a);
		}
		System.out.println("====================");
		hc.sort(node);
		hc.huffman(hc.sort(node));
		hc.get(hc.root);
	}
}

你可能感兴趣的:(java,算法)