Java 实现Haffman树

Haffman Tree 的Java实现

I 哈夫曼树概念:

        给定n个权值作为n个叶子结点,构造一棵二叉树,若带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。(from Baidu百科)。

II 哈夫曼树的应用

    1、哈夫曼编码

    2、常应用于信息检索

    etc.

III 常用术语

    

哈夫曼树(霍夫曼树)又称为最优树.
1、路径和路径长度
在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。
2、结点的权及带权路径长度
若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。

3、树的带权路径长度
树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL。
哈夫曼树






IV 下面重点介绍一下haffman Tree的Java实现,代码附下:

package pers.me.timlong.tree;

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

public class HaffmanTree {

	/**
	 * 内部静态类Node
	 * @author lenovo
	 *
	 * @param <E>
	 */
	public static class Node<E>{
		private E data;
		private double weight;
		private Node<E> leftChild;
		private Node<E> rightChild;

		public Node(E data, double weight) {
			this.data = data;
			this.weight = weight;
		}

		@Override
		public String toString() {
			return "Node[data = " + this.data + ", weight = " + this.weight + "]";
		}
	}

	private static <E> void swap(List<Node<E>> nodes, int i, int j) {
		Node<E> temp;
		temp = nodes.get(i);
		nodes.set(i, nodes.get(j));

		nodes.set(j, temp);
	}
	
	//实现快速排序,对节点进行排序
	private static <E> void subSort(List<Node<E>> nodes, int start, int end) {
		if(start < end) {
			Node<E> base = nodes.get(start);
			int i = start;
			int j = end + 1;
			while(true) {
				while(i < end && nodes.get(++ i).weight >= base.weight) ;
				while(j > start && nodes.get(-- j).weight <= base.weight) ;
				
				if(i < j)
					swap(nodes, i, j);
				else 
					break;
			}
			
			swap(nodes, start, j);
			subSort(nodes, start, j);
			subSort(nodes, start, j - 1);
		}
	}
	
	public static <E> void quickSort(List<Node<E>> nodes) {
		subSort(nodes, 0, nodes.size() - 1);
	}
	
	@SuppressWarnings("rawtypes")
	public static List<Node> breadthFirst(Node root){
		Queue<Node> queue = new ArrayDeque<>();
		List<Node> list = new ArrayList<Node>();
		if(null != root) {
			queue.offer(root);
		}
		while(! queue.isEmpty()) {
			list.add(queue.peek());  //not remove
			Node p = queue.poll();  //remove
			if(null != p.leftChild) {
				queue.offer(p.leftChild);
			}
			if(null != p.rightChild) {
				queue.offer(p.rightChild);
			}
		}
		return list;
	}
	
	public static<E> Node<E> createTree(List<Node<E>> nodes){
		while(nodes.size() > 1) {
			quickSort(nodes);
			Node<E> left = nodes.get(nodes.size()  - 1);
			Node<E> right = nodes.get(nodes.size() - 2);
			
			Node<E> parent = new Node<E>(null, left.weight + right.weight);
			parent.leftChild = left;
			parent.rightChild = right;
			
			nodes.remove(nodes.size() - 1);
			nodes.remove(nodes.size() - 1);
			
			nodes.add(parent);
			
		}
		
		return nodes.get(0);
	}
		
	public static void main(String[] args) {
		List<Node<String>> nodes = new ArrayList<Node<String>>();
		nodes.add(new Node<String>("A", 40.0));
		nodes.add(new Node<String>("B", 7.0));
		nodes.add(new Node<String>("C", 10.0));
		nodes.add(new Node<String>("D", 30.0));
		nodes.add(new Node<String>("E", 12.0));
		nodes.add(new Node<String>("F", 2.0));
		Node<String> root = HaffmanTree.createTree(nodes);
		System.out.println(HaffmanTree.breadthFirst(root));
	}
}

打印结果:

[Node[data = null, weight = 101.0], 
Node[data = null, weight = 44.0],
Node[data = null, weight = 57.0], 
Node[data = null, weight = 14.0], 
Node[data = D, weight = 30.0], 
Node[data = null, weight = 17.0], 
Node[data = A, weight = 40.0], 
Node[data = F, weight = 2.0], 
Node[data = E, weight = 12.0], 
Node[data = B, weight = 7.0], 
Node[data = C, weight = 10.0]]

    在编程中的应用无处不在,掌握数据结构的底层实现,无疑可以更好地帮助我们提高编程能力与开发效率。

      望每天进步一点,再见

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章