數據結構第四章 哈夫曼樹和哈夫曼編碼的Java實現

 參考博客:https://blog.csdn.net/qq_33366446/article/details/70251518

哈夫曼樹:每次取出數組中兩個值最小的節點(利用最小堆)合併成一棵樹,根節點的值爲兩各節點的值的和,然後把根節點塞回堆中,再取出兩個值最小的節點合併(左節點小於等於右節點),不斷循環直到所有節點合成一棵樹。

這棵樹每個葉節點到根節點的距離乘其權重的積的和最小。

如果讓把往左的節點編碼+“0”,往右的+“1”就可以得到哈夫曼編碼

import java.util.*;

public class test {
	public static void main(String[] args) {
    //測試
		int[] a = {1,2,3,4,5,6};
		HuffmanTree test = new HuffmanTree(a);
		test.preOrder();
		System.out.println();
		test.printHuffmanCode();
	}
}

//哈夫曼樹類
class HuffmanTree {
	Node root = null;
	
    //節點類
	class Node implements Comparable<Node> {
		private int data = 0;
		private Node leftChild = null;
		private Node rightChild = null;
		public Node(int data) {
			this.data = data;
	    }
		public Node(int data, Node leftChild, Node rightChild) {
		    this.data = data;
		    this.leftChild = leftChild;
		    this.rightChild = rightChild;
	    }
		
		public int getData() {
			return data;
		}
		public void setData(int data) {
			this.data = data;
		}
		
		public Node getLeftChild() {
			return leftChild;
		}
		public void setLeftChild(Node leftChild) {
			this.leftChild = leftChild;
		}
		
		public Node getRightChild() {
			return rightChild;
		}
		public void setRightChild(Node rightChild) {
			this.rightChild = rightChild;
		}
		
		@Override
		public int compareTo(Node other) {
			// TODO Auto-generated method stub
			return this.getData() - other.getData();
		}	
	}
	
	public HuffmanTree (int[] weight) { //weight是權重
		buildHuffmanTree(weight);
	}
	
	/**
	 * 構建哈夫曼樹:將輸入數組轉化爲節點數組再導入小根堆,再導出(取出兩個,合併data再放回)
	 */
	public void buildHuffmanTree(int[] weight) {
		PriorityQueue<Node> priorityQueue = new PriorityQueue<Node>();
		int weightLength = weight.length;
		Node[] nodes = new Node[weightLength];
		for (int i = 0; i < weightLength; i++) {
			nodes[i] = new Node(weight[i]);
			priorityQueue.add(nodes[i]);
		}
		Node temporary1 = null;
		Node temporary2 = null;
		Node together = null;
		for (int i = 0; i < weightLength-1; i++) {//取兩放一等於每次取一個,最後一個另外處理所以要減一
			temporary1 = priorityQueue.poll();
			temporary2 = priorityQueue.poll();
			together = new Node(temporary1.getData() + temporary2.getData(), temporary1, temporary2);
			priorityQueue.add(together);
		}
		root = priorityQueue.poll();
	}
	
	/**
	 * 前序遍歷
	 */
	public void preOrder() {
		if (root != null) {
			 preOrderDetail(root);
		}
	}
	public void preOrderDetail(Node node) {
		if (node != null) {
			System.out.print(node.data);
			System.out.print(" ");
			preOrderDetail(node.leftChild);
			preOrderDetail(node.rightChild);
		}
	}	
	
	public void printHuffmanCode() {
		printHuffmanCodeDetail(root, "");
	}
	
	/**
	 *  輸出哈夫曼編碼
	 */
	public static void printHuffmanCodeDetail(Node node, String huffmanCode) { 
		if (node.getLeftChild() == null && node.getRightChild() == null) {
			System.out.println("權值爲" + node.getData() + "的結點的編碼爲:" + huffmanCode);
		}
        //如果不是葉節點則繼續往下遍歷
		if (node.getLeftChild() != null) {
			printHuffmanCodeDetail(node.getLeftChild(), huffmanCode + "0");
		}
		if (node.getRightChild() != null) {
			printHuffmanCodeDetail(node.getRightChild(), huffmanCode + "1");
		}
		
	}
}

 

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