实现哈夫曼树

手写实现哈夫曼树的编码功能:

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
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值