数据结构第四章 哈夫曼树和哈夫曼编码的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");
		}
		
	}
}

 

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