代码改变世界

哈夫曼树

2012-10-09 10:55  jiutianhe  阅读(224)  评论(0编辑  收藏  举报

哈夫曼树又称最优二叉树

哈夫曼树的构造

  

哈夫曼树的构造

  假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为:

  (1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);

  (2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;

  (3)从森林中删除选取的两棵树,并将新树加入森林;

  (4)重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。

 编程实现:

package binarytree;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Queue;

public class HuffmanTree<T> {
	public class Node{
		T data;
		double weight;
		Node lchild;
		Node rchild;
		public Node(T data, double weight) {
			this.data = data;
			this.weight = weight;
		}
		@Override
		public String toString() {
			return "Node [data=" + data + ", weight=" + weight + "]";
		}		
	}
	/**
	 * 构造哈夫曼树
	 * @param nodes节点集合
	 * @return 哈夫曼根节点
	 */
	public Node createTree(List<Node> nodes){
		int size=nodes.size();
		while (size>1) {
			quickSort(nodes,0,size-1);
			Node left=nodes.get(size-1);
			Node right=nodes.get(size-2);
			Node parent=new Node(null, left.weight+right.weight);
			parent.lchild=left;
			parent.rchild=right;
			nodes.remove(size-1);
			nodes.remove(size-2);
			nodes.add(parent);
		}
		return nodes.get(0);
	}
	//降序排列的快速排序
	private void quickSort(List<Node> nodes, int l, int u) {
		if (l>=u) {
			return;
		}
		Node temp=nodes.get(l); int i=l; int j=u;
		
		while(i<j){
			for (; i < j && nodes.get(i).weight>=temp.weight; i++);
			for (; i < j && nodes.get(j).weight<temp.weight; j--);						
			if (i>j) {
				break;
			}
			Collections.swap(nodes, i, j);
		}
		
		Collections.swap(nodes, j, l);
		quickSort(nodes, l, j-1);
		quickSort(nodes, j+1, u);
		
	}
	//广度优先遍历
	public List<Node> breadthFrist(Node root){
		Queue<Node> queue=new ArrayDeque<Node>();
		List<Node> list=new ArrayList<Node>();
		if (root!=null) {
			queue.offer(root);
		}
		while (!queue.isEmpty()) {
			list.add(queue.peek());
			Node pNode=queue.poll();
			if (pNode.lchild!=null) {
				queue.offer(pNode.lchild);
			}
			if (pNode.rchild!=null) {
				queue.offer(pNode.rchild);
			}
		}
		return list;
	}
}