[java]java實現哈夫曼編碼

torrrino發表於2017-04-06

二叉樹的結點類:該類中包含結點的基本資訊,在二叉樹中的位置資訊以及用flag表明該結點是否參加二叉樹構造

/**
 * @author:zym
 * @description:node of binary tree
 * @date: 2017/4/6
 */
public class Node {
	public String name;//節點符號
	public int weight;//權重
	public Node parent;
	public Node leftChild;
	public Node rightChild;
	public boolean flag;
	public StringBuffer code;
	
	public Node(String n,int w){//不同包中的類對該方法的訪問許可權?
		name = n;
		weight = w;
		flag = true;
		code = new StringBuffer();
	}

	@Override
	public String toString() {
		return "Node [name=" + name + ", weight=" + weight + ", code=" + code + "]";
	}
	
}

排序類:採用快速排序對結點權重逆序排序

/**
 * @author:zym
 * @description: include all kinds of sort method
 * @date: 2017/4/6
 */
public class Sort {
	
	public static void swap(List<Node> nodes,int i,int j){
		Node temp = nodes.get(i);
		nodes.set(i, nodes.get(j));
		nodes.set(j, temp);
	} 	
	
	/**
	 * author:zym
	 * description: quickSort of List(reverse sequence)
	 * date:2017/4/6
	 */
	public static void quickSort(List<Node> nodes,int begin,int end){
		if(begin<end){
			Node key = nodes.get(begin);
			int i = begin,j = end;
			while(true){
				while(i<end&&nodes.get(i).weight>=key.weight) i++;
				while(j>begin&&nodes.get(j).weight<=key.weight) j--;
				
				if(i<j) swap(nodes,i,j);
				else break;
			}
			swap(nodes,begin,j);
			quickSort(nodes,begin,j-1);
			quickSort(nodes,j+1,end);
		}
	}
	
}


哈夫曼編碼類:構造哈夫曼二叉樹並編碼

/**
 * @author:zym
 * @description: data structure of huffman binary tree
 * @date:2017/4/6
 */
public class HuffmanCode {
	public static void createTree(List<Node> nodes){
		Node left = null,right = null;
		int k = 0,//記錄下第一次遍歷的斷點
			size = nodes.size();//記錄nodes的初始結點數
	    
		while(true){
			Sort.quickSort(nodes, 0, nodes.size()-1);
			for(int i=1;i<nodes.size();i++){
				if(nodes.get(nodes.size()-i).flag){
					left = nodes.get(nodes.size()-i);
					k = i;
					break;	
				}
				left = null;
			}
			for(int j=k+1;j<nodes.size();j++){
				if(nodes.get(nodes.size()-j).flag){
					right = nodes.get(nodes.size()-j);
					break;
				}
				right = null;
			}
			if(left!=null&&right!=null){
				Node parent = new Node(null,left.weight+right.weight);
				parent.leftChild = left;
				parent.rightChild = right;
				left.parent = parent;
				right.parent = parent;
				left.flag = false;
				right.flag = false;
				nodes.add(parent);	
			}
			if(nodes.size()==2*size-1){
				Sort.quickSort(nodes, 0, nodes.size()-1);
				break;
			}
		}
	}
	
	/**
	 * author:zym
	 * description: code for huffman binary tree
	 * date:
	 */
	public static void codeTree(List<Node> nodes){
		for(int i=1;i<nodes.size();i++){
			if(nodes.get(nodes.size()-i).name!=null){//查詢到所有葉子結點
				Node temp = nodes.get(nodes.size()-i),//暫存葉子結點
				     temp1 = null,//暫存待編碼結點
				     parent = null;
				while(true){
					if(temp1 == null) temp1 = temp;
					if(temp1.parent!=null){ 
						parent = temp1.parent;
					}
					else break;
					if(parent.leftChild == temp1) temp.code.append("0");
					else temp.code.append("1");
					temp1 = parent;
				}
				//temp = nodes.get(nodes.size()-i);
				temp.code = temp.code.reverse();
			}
		}
	}
}

Test類

public class TestHuffmanCode {
	
	public static void main(String[] args){
		List<Node> nodes = new ArrayList<Node>();	
		nodes.add(new Node("a",4));
		nodes.add(new Node("b",6));
		nodes.add(new Node("c",5));
		nodes.add(new Node("d",12));
		nodes.add(new Node("e",3));
		
		HuffmanCode.createTree(nodes);
		HuffmanCode.codeTree(nodes);
		
		for(Node node:nodes){
			if(node.name!=null) System.out.println(node.toString());
		}
	}	
}

輸出結果:




相關文章