哈夫曼树与哈夫曼编码

哈夫曼编码使用在编码领域,可以有效的压缩存储空间,我们的程序分为两部分,第一部分是哈夫曼树的节点类,定义了它的码值,权重(即出现频率),左右孩子节点与双亲节点,初始化时后三者都是空的。

代码如下

public class HTNode {
	private char data;
	private int weight;
	private HTNode parent;
	private HTNode left;
	private HTNode right;
	
	public HTNode(char data, int weight) {
		this.data = data;
		this.weight = weight;
		this.parent=null;
		this.left=null;
		this.right=null;
	}
	public char getData() {
		return data;
	}
	public void setData(char data) {
		this.data = data;
	}
	public int getWeight() {
		return weight;
	}
	public void setWeight(int weight) {
		this.weight = weight;
	}
	public HTNode getParent() {
		return parent;
	}
	public void setParent(HTNode parent) {
		this.parent = parent;
	}
	public HTNode getLeft() {
		return left;
	}
	public void setLeft(HTNode left) {
		this.left = left;
	}
	public HTNode getRight() {
		return right;
	}
	public void setRight(HTNode right) {
		this.right = right;
	}
	
	

}

之后我们编写一个工厂类,用于生成哈夫曼树与哈夫曼编码,只需输入一个由树节点组成的数组,即可以得到对应的哈夫曼编码,代码如下

public class TreeBuilder {
	
	public static HTNode[] createHT(HTNode[] nodes){
		int len=nodes.length*2-1;
		HTNode[] tree=new HTNode[len];
		for(int i=0;i<nodes.length;i++){
			tree[i]=new HTNode(nodes[i].getData(),nodes[i].getWeight());
		}
		for(int i=nodes.length;i<len;i++){
			tree[i]=new HTNode(' ', 0);
		}
		for(int i=nodes.length;i<len;i++){
			int min1=9999;
			int min2=9999;
			int left=-1;
			int right=-1;
			for(int k=0;k<i;k++){
				if(tree[k].getParent()==null){
					if(tree[k].getWeight()<=min1){
						min2=min1;
						right=left;
						min1=tree[k].getWeight();
						left=k;
					}
					else{
						if(tree[k].getWeight()<min2){
							min2=tree[k].getWeight();
							right=k;
						}
					}
				}
			}
			tree[i].setWeight(tree[right].getWeight()+tree[left].getWeight());
			tree[i].setLeft(tree[left]);
			tree[i].setRight(tree[right]);
			tree[left].setParent(tree[i]);
			tree[right].setParent(tree[i]);
		}
		return tree;
//		for(int i=0;i<len;i++){
//			System.out.print(tree[i].getWeight()+" ");
//		}
	}
	
	public static void createHTCode(HTNode[] nodes){
		int len=nodes.length*2-1;
		HTNode[] tree=new HTNode[len];
		tree=createHT(nodes);
		HTNode p=null;
		HTNode parent=null;
		StringBuilder[] codes=new StringBuilder[nodes.length];
		
		for(int i=0;i<nodes.length;i++){
			p=tree[i];
			parent=p.getParent();
			while(parent!=null){
				if(parent.getLeft()==p){
					if(codes[i]==null){
						codes[i]=new StringBuilder("0");
					}
					else{
//						sb.Insert(0, "tt");
						codes[i].insert(0, "0");
					}
				}
				if(parent.getRight()==p){
					if(codes[i]==null){
						codes[i]=new StringBuilder("1");
					}
					else{
						codes[i].insert(0, "1");
					}
				}
				p=parent;
				parent=p.getParent();
			}
		}
		for(int i=0;i<codes.length;i++){
			System.out.println(codes[i]);
		}
		
	}
	
	
	public static void main(String args[]){
		HTNode n1=new HTNode('a',3);
		HTNode n2=new HTNode('b',4);
		HTNode n3=new HTNode('a',5);
		HTNode n4=new HTNode('a',6);
		HTNode[] nodes={n1,n2,n3,n4};
		createHTCode(nodes);
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值