java赫夫曼树

赫夫曼树:是一个权值最大的结点离根结点最近的优化树

权值就是每个结点的值

路径是通过一个结点往下可以达到孩子或孙子结点之间的通路

树的带权路径长度是所有叶子结点的带权路径长度与该结点的乘积 记为WPL

WPL最小的就是赫夫曼树

权值最大的结点距离根结点最近的二叉树是最右二叉树

从根结点到E的路径长度就是E结点的层数减去根结点的层数就是路径长度

E的带权路径长度就是它的路劲长度*E的权值=E的带权路径长度

假设把13,7,8,29,6,1组成一个赫夫曼树的各个结点的权值

首先需要把这些数做一个排序然后取出最小的两个结点

这最小的两个结点之和作为这个结点的父结点

重复步骤就可以组成一个赫夫曼树

 最终树的结构就是:

 

创建二叉树:

/**
 * 实现Comparable借口 方便排序结点的权值
 */
public class node implements Comparable<node> {
    /*
    创建树的结点
    id表示树的权值
    left right左右子树
     */
    private int id;
    private node left;
    private node right;
    /*
    前序遍历二叉树
     */
    public void preSelect(){
        System.out.println(this);
        if(this.getLeft()!=null) this.getLeft().preSelect();
        if(this.getRight()!=null) this.getRight().preSelect();
    }

    public node(int id) {this.id = id;}

    public int getId() {return id;}

    public void setId(int id) {this.id = id;}

    public node getLeft() {return left;}

    public void setLeft(node left) {this.left = left;}

    public node getRight() {return right;}

    public void setRight(node right) {this.right = right;}

    @Override
    public String toString() {return "node{" + "id=" + id + '}';}
    /*
    实现排序
    此结点的权值减去对比结点的权值
    大于返回1或以上
    等于返回0
    小于返回负数
     */
    @Override
    public int compareTo(node o) {return this.id-o.id;}

}

将普通二叉树转为赫夫曼树:

/**
 * 赫夫曼树的转化操作及创建
 */
public class HuffmanTree {
    /**
     * 传进来是需要转换的数组每个元素就是权值
     * 返回的一定是根结点
     * @param array
     * @return
     */
    public node HuffmanChange(int[] array){
        /*
        创建集合存放结点
         */
        List<node> nodes = new ArrayList<node>();
        /*
        集合的每个结点以数组的元素创建到集合中去
         */
        for(int i:array){
            nodes.add(new node(i));
        }
        /*
        1,集合排序Collections.sort
        2,取出集合中权值最小的两个结点组成一个新的结点作为这两个结点的父结点
        3,既然集合中最小的两位数已经用过了就把他们删除
        4,将新的结点放到集合中来进行下一轮的排序迭代创建新结点
         */
        while(nodes.size()>1){
            Collections.sort(nodes);
            node leftNode = nodes.get(0);
            node rightNode = nodes.get(1);
            node newNode = new node(leftNode.getId()+rightNode.getId());
            newNode.setLeft(leftNode);
            newNode.setRight(rightNode);
            nodes.remove(0);
            nodes.remove(0);
            nodes.add(newNode);
        }
        //集合中一定会剩下一个元素因为nodes.size()>1的条件限制
        //也是最后两个数的父结点也就是最后的根结点
        System.out.println(nodes.size());
        /*
        返回集合中仅剩的元素
         */
        return nodes.get(0);
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值