【Java】构造哈夫曼树并计算带权路径长度

思想

先构建一个线性表,将树的结点存入,然后对树的结点进行升序排序,这样就保证了线性表的前两个结点是值最小的两个结点。然后根据构造哈夫曼树的方法,取值最小的两个结点分别为新树的左右子树,而新树的值就是这两个结点值的和。接着再将新树结点加入线性表,并将线性表排序。重复操作,直到链表只剩一个结点,而这个结点就是哈夫曼树的头结点。

而寻找带权路径长度可以使用递归的方法。

代码

public class Main {
    public static void main(String[] args) {
        //树节点及其方法
        class Treenode {
            int value;
            Treenode lchild = null;
            Treenode rchild = null;

            public Treenode(int value) {
                this.value = value;
            }
            //计算带权路径长度,采用递归的方法,level代表层数,初始为0
            //递归计算部分不怎么好理解,可以自己画图试试看
            public int haffman(int level, int sum) {
                //当左子树和右子树为空时,则表示为哈夫曼树的叶子结点
                if (lchild == null && rchild == null) {
                    sum += level * value;
                    return sum;
                }
                //否则不为空时,分别遍历左子树和右子树
                sum = lchild.haffman(level + 1, sum);
                sum = rchild.haffman(level + 1, sum);
                return sum;
            }
        }
        
        //构建一个链表
        List<Treenode> list = new ArrayList<>();
        Scanner sc = new Scanner(System.in);
        //告诉程序有几个数需要输入
        int value = sc.nextInt();
        System.out.println("get it");
        for (int i = 0; i < value; i++) {
            Treenode node = new Treenode(sc.nextInt());
            list.add(node);
            System.out.println("ok");
        }
        //对线性表进行排序
        list.sort(new Comparator<Treenode>() {
            @Override
            public int compare(Treenode o1, Treenode o2) {
                if (o1.value >= o2.value) {
                    return 1;
                } else {
                    return -1;
                }
            }
        });
        //当链表的长度大于1的时候,构建哈夫曼树
        while (list.size() > 1) {
            Treenode temp = new Treenode(list.get(0).value + list.get(1).value);
            temp.lchild = list.get(0);
            temp.rchild = list.get(1);
            list.remove(0);
            list.remove(0);
            list.add(temp);
            //插入新结点后,对线性表重新排序
            list.sort(new Comparator<Treenode>() {
                @Override
                public int compare(Treenode o1, Treenode o2) {
                    if (o1.value >= o2.value) {
                        return 1;
                    } else {
                        return -1;
                    }
                }
            });
        }
        //链表的第一个节点即为哈夫曼树的根节点
        Treenode t = list.get(0);
        //计算带权路径长度
        int sum = t.haffman(0, 0);
        System.out.println(sum);
    }
}

代码2
思想:将上述线性表改为优先级队列。

public class Main {
    public static void main(String[] args) {
        class Treenode {
            int value;
            Treenode lchild = null;
            Treenode rchild = null;

            public Treenode(int value, Treenode lchild, Treenode rchild) {
                this.value = value;
                this.lchild = lchild;
                this.rchild = rchild;
            }

            public Treenode(int value) {
                this.value = value;
            }

            public int haffman(int level, int sum) {
                if (lchild == null && rchild == null) {
                    sum += level * value;
                    return sum;
                }
                sum = lchild.haffman(level + 1, sum);
                sum = rchild.haffman(level + 1, sum);
                return sum;
            }
        }
        Queue<Treenode> queue = new PriorityQueue<>(new Comparator<Treenode>() {
            @Override
            public int compare(Treenode o1, Treenode o2) {
                return o1.value - o2.value;
            }
        });
        Scanner sc = new Scanner(System.in);
        int value = sc.nextInt();
        System.out.println("get it");
        for (int i = 0; i < value; i++) {
            Treenode node = new Treenode(sc.nextInt());
            queue.add(node);
            System.out.println("ok");
        }
        while (queue.size() > 1) {
            Treenode lchild = queue.poll();
            Treenode rchild = queue.poll();
            Treenode temp = new Treenode(lchild.value + rchild.value, lchild, rchild);
            queue.add(temp);
        }

        Treenode t = queue.peek();
        int sum = t.haffman(0, 0);
        System.out.println(sum);
    }
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值