数据结构-哈夫曼树

哈夫曼树被称为最优二叉树。是一类带权路径最短的二叉树。

节点之间的路径长度:从一个节点到另一个节点之间的分支数量称为两个节点之间的路径长度。

树的路径长度:从根节点到树中每一个节点的路径长度之和。

节点的带权路径长度:从该节点到根节点之间的路径长度与节点上权的乘积。

树的带权路径长度:树中所有叶子节点的带权路径长度之和。

带权路径最小的二叉树被称为哈夫曼树或最优二叉树。

简单代码实现:

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;

/**
 * Created by Administrator on 2018/3/15.
 */
public class HuffmanTree {

    public static class Node<E> {
        E data;
        double weight;
        Node leftChild;
        Node rightChild;

        public Node(E data, double weight) {
            this.data = data;
            this.weight = weight;
        }

        public String toString() {
            return "Node[data=" + data + ", weight=" + weight + "]";
        }
    }

    public static void main(String[] args) {
        List<Node> nodes = new ArrayList<>();
        nodes.add(new Node("A", 40.0));
        nodes.add(new Node("B", 8.0));
        nodes.add(new Node("C", 10.0));
        nodes.add(new Node("D", 30.0));
        nodes.add(new Node("E", 10.0));
        nodes.add(new Node("F", 2.0));
        Node root = createTree(nodes);
        System.out.println(breadthFirst(root));
    }

    private static Node createTree(List<Node> nodes) {
        while (nodes.size() > 1) {
            quickSort(nodes);
            Node left = nodes.get(nodes.size() - 1);
            Node right = nodes.get(nodes.size() - 2);
            Node parent = new Node(null, left.weight + right.weight);
            parent.leftChild = left;
            parent.rightChild = right;
            nodes.remove(nodes.size() - 1);
            nodes.remove(nodes.size() - 1);
            nodes.add(parent);
        }
        return nodes.get(0);
    }

    private static void swap(List<Node> nodes, int i, int j) {
        Node tmp;
        tmp = nodes.get(i);
        nodes.set(i, nodes.get(j));
        nodes.set(j, tmp);
    }

    private static void subSort(List<Node> nodes, int start, int end) {
        if (start < end) {
            Node base = nodes.get(start);
            int i = start;
            int j = end + 1;
            while (true) {
                while (i < end && nodes.get(++i).weight >= base.weight) ;
                while (j > start && nodes.get(--j).weight <= base.weight) ;
                if (i < j) {
                    swap(nodes, i, j);
                } else {
                    break;
                }
            }
            swap(nodes, start, j);
            subSort(nodes, start, j - 1);
            subSort(nodes, j + 1, end);
        }
    }

    public static void quickSort(List<Node> nodes) {
        subSort(nodes, 0, nodes.size() - 1);
    }

    public static List<Node> breadthFirst(Node root) {
        Queue<Node> queue = new ArrayDeque<>();
        List<Node> list = new ArrayList<>();
        if (root != null) {
            queue.offer(root);
        }
        while (!queue.isEmpty()) {
            list.add(queue.peek());
            Node p = queue.poll();
            if (p.leftChild != null) {
                queue.offer(p.leftChild);
            }
            if (p.rightChild != null) {
                queue.offer(p.rightChild);
            }
        }

        return list;
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值