菜鸟说:哈夫曼树及哈弗曼编码

终于把哈夫曼树及哈弗曼编码弄好了~

 

哈夫曼树就是最优二叉树

 

和上次的搜索二叉树一样,哈夫曼树也有它特定的构造规则:

 

1.要把要存入哈夫曼树的数据分别创建一个树

 

2.把这些树按照大小顺序排序(在Java里面用优先队列PriorityQueue非常方便)

 

3.去两个最小的树,把他们合并在一块儿,并把合并后的树放回队列,如此递归往复……

 

4.把最后剩下的那个树设置为根节点。

 

这样,哈夫曼树就构造完成了~

 

检查方法就是把哈夫曼树的所有叶结点的编码都输出来,向左走编码为0,向右走编码为1(根据自己规定)

 

然后再根据编码把树画出来,检查~

 

首先是节点类:

/**
 * 哈夫曼树节点类
 * @author Micro
 *
 */
public class HafNode implements Comparable<HafNode>{
	private HafNode father;
	private HafNode left;
	private HafNode right;
	private int num;
	
	//重载构造器
	public HafNode (int num) {
		this.num=num;
	}
	
	
	public HafNode getFather() {
		return father;
	}
	public void setFather(HafNode father) {
		this.father = father;
	}
	public HafNode getLeft() {
		return left;
	}
	public void setLeft(HafNode left) {
		this.left = left;
	}
	public HafNode getRight() {
		return right;
	}
	public void setRight(HafNode right) {
		this.right = right;
	}
	public int getNum() {
		return num;
	}
	public void setNum(int i) {
		this.num = i;
	}

	//设置要比较的对象
	@Override
	public int compareTo(HafNode o) {
		// 要比较的是数字大小
		int P = o.getNum();
		return num-P;
	}
}

 

 然后就是建树过程和输出哈弗曼编码:

 

import java.util.PriorityQueue;

/**
 * 创建哈夫曼树并获得各叶节点的哈弗曼编码
 * 
 * @author Micro
 * 
 */
public class HafTest {

	// 创建根节点
	private static HafNode root;

	// 程序入口
	public static void main(String[] args) {
		// 创建一个数组
		int[] a = { 1, 4, 3, 5, 6 ,4,6,7,6};
		// 创建优先队列
		PriorityQueue<HafNode> queue = new PriorityQueue<HafNode>();
		HafTest ht = new HafTest();
		// 把每个数新建一个节点
		for (int i = 0; i < a.length; i++) {
			HafNode hf = new HafNode(a[i]);
			queue.add(hf);
		}
		ht.HafTree(queue);
		String Code = "";
		ht.print(root, Code);
	}

	// 创建哈夫曼树
	public void HafTree(PriorityQueue<HafNode> queue) {
		while (queue.size() > 1) {
			HafNode min1, min2;
			min1 = queue.poll();
			min2 = queue.poll();
			// 创建合并的节点
			HafNode result = new HafNode(min1.getNum() + min2.getNum());
			result.setLeft(min1);
			result.setRight(min2);
			min1.setFather(result);
			min2.setFather(result);
			queue.add(result);
		}
		root = queue.peek();
	}

	// 打印叶节点
	public void print(HafNode a, String Code) {

		if (a.getLeft() == null && a.getRight() == null) {
			System.out.println(a.getNum() + "的哈夫曼编码为:" + Code);
		}
		if (a.getLeft() != null) {
			print(a.getLeft(), Code + '0');
		}
		if (a.getRight() != null) {
			print(a.getRight(), Code + '1');
		}
	}
}

 

输出的结果为:

 

4的哈夫曼编码为:000

1的哈夫曼编码为:0010

3的哈夫曼编码为:0011

4的哈夫曼编码为:010

5的哈夫曼编码为:011

6的哈夫曼编码为:100

6的哈夫曼编码为:101

6的哈夫曼编码为:110

7的哈夫曼编码为:111


恩~~没有错误~~

 

这样,一个最基本的哈夫曼树就完成了,下面就是利用这个树实现文件的压缩~加油~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值