手写实现哈夫曼树的编码功能:
package com.example.admin.myapplication.tree; /** * 哈夫曼树 * Created by admin on 2017/11/16. */ public class HuffmanTree { private SortLinkQueue linkQueue; public HuffmanTree() { linkQueue = new SortLinkQueue(); } /** * 哈夫曼编码 * @param array */ public void huffmanEncoding(int[] array) { for (int value : array) { linkQueue.add(createNode(value)); } while (linkQueue.size() > 1) { Node<Integer> l = linkQueue.offer(); l.code = 0; Node<Integer> r = linkQueue.offer(); r.code = 1; Node<Integer> compound = createNode(l.value + r.value); compound.liftChild = l; compound.rightChild = r; linkQueue.add(compound); } traversal(linkQueue.offer()); } /** * 遍历哈夫曼数生成编码 * @param node */ private void traversal(Node node) { if (node == null) { return; } if (node.liftChild != null) { node.liftChild.encoding = node.encoding + node.liftChild.code; traversal(node.liftChild); } if (node.rightChild != null) { node.rightChild.encoding = node.encoding + node.rightChild.code; traversal(node.rightChild); } if (node.liftChild == null && node.rightChild == null) { System.out.println(node.value + " 编码为: " + node.encoding); } } /** * 创建一个节点 * @param value * @return */ private Node<Integer> createNode(int value) { Node<Integer> node = new Node<>(); node.value = value; return node; } /** * 排序队列 */ class SortLinkQueue { /** * 指向队头 */ private Node<Integer> head; /** * 指向队尾 */ private Node<Integer> last; int count = 0; /** * 取出并删除队首元素 * * @return */ Node<Integer> offer() { if (count <= 0 || head == null) { return null; } Node node = head; head = head.next; if (node.next != null) { node.next.parent = null; node.next = null; } count--; return node; } /** * 添加一个节点 * * @param node */ void add(Node<Integer> node) { if (head == null) { head = node; last = node; } else { Node<Integer> n = head; for (; n != null; ) { if (node.value > n.value) { n = n.next; } else { break; } } if (n != null) {//找到比添加值大的 if (n.parent == null) {//头结点 head = node; node.next = n; n.parent = node; } else { node.next = n; node.parent = n.parent; node.parent.next = node; n.parent = node; } } else { last.next = node; node.parent = last; last = node; } } count++; } int size() { return count; } } class Node<T> { /** * 编码 */ String encoding = ""; T value; /** * 编码,0左子树,1右子数 */ int code; Node liftChild; Node rightChild; Node next; Node parent; } }
测试:
int[] dataArray = {23, 10, 15, 20, 50, 21, 8, 6, 13}; HuffmanTree huffmanTree = new HuffmanTree(); huffmanTree.huffmanEncoding(dataArray);
结果:
11-16 18:54:45.224 21473-21473/com.example.admin.myapplication I/System.out: 6 编码为: 0000 11-16 18:54:45.224 21473-21473/com.example.admin.myapplication I/System.out: 8 编码为: 0001 11-16 18:54:45.224 21473-21473/com.example.admin.myapplication I/System.out: 15 编码为: 001 11-16 18:54:45.224 21473-21473/com.example.admin.myapplication I/System.out: 20 编码为: 010 11-16 18:54:45.224 21473-21473/com.example.admin.myapplication I/System.out: 21 编码为: 011 11-16 18:54:45.224 21473-21473/com.example.admin.myapplication I/System.out: 10 编码为: 1000 11-16 18:54:45.224 21473-21473/com.example.admin.myapplication I/System.out: 13 编码为: 1001 11-16 18:54:45.224 21473-21473/com.example.admin.myapplication I/System.out: 23 编码为: 101 11-16 18:54:45.224 21473-21473/com.example.admin.myapplication I/System.out: 50 编码为: 11