9、哈夫曼树的实现

    哈夫曼树也称为最优二叉树,是指对于一组有确定权值的叶结点、构造的具有最小带权路径长度的二叉树。给你的问题是,提供一组n个整数权值,请你完成构建该组权值的哈夫曼树。
输入:标准输入,输入的第一行为一个正整数,其值代表需要构建二叉树的叶结点的个数n;输入的第二行为n个由一个空格隔开的正整数,表示叶结点的权值;输入的第三行为n个字符,对应第二行的权值的叶结点的名称;
输出:标准输出,输出构建的哈夫曼树的每个叶结点的访问路径,即从根到叶结点的路径,如果是走左输出l,如果走右输出r。每行输出一个叶结点信息,输出格式为:先输出该结点的名称,再输出冒号,接下来,输出路径,中间仅一个空格隔开。按照输入叶结点的名称次序分别使用n行输出。
测试样例:
输入:
4
7 5 3 1
abcd
输出:
a:l
b:r r
c:r l r
d:r l l

说明,为了进行系统判断,在构建哈夫曼树时,要求:
(1)选择两个权值小的结点在构建子树时,小的结点为左子树,较大的为右子树;
(2)如果存在两个权值相同,以出现的顺序依次为左右子树;
提示:
在构建哈夫曼树时,提供设计的结点对象参考如下:
public class HFMTreeNode {
 int weight,parent,lchild,rchild;
 HFMTreeNode(){
  weight=0;
  parent=lchild=rchild=-1;
 }
}

import java.util.Scanner;

public class Main{
    public static void main(String[] args) {
        HFMTree ht = new HFMTree();
        ht.create();
        ht.print();
    }
}

class HFMTreeNode {
    int weight,parent,lchild,rchild;
    HFMTreeNode(){
        weight=0;
        parent=lchild=rchild=-1;
    }
}

class HFMTree{
    private HFMTreeNode[] data;
    private int leafNum;
    private String str;

    public void create() {
        Scanner sc = new Scanner(System.in);
        leafNum = sc.nextInt();
        data = new HFMTreeNode[2 * leafNum - 1];
        for (int i = 0; i < 2 * leafNum - 1; ++i) {
            data[i] = new HFMTreeNode();
        }
        for (int i = 0; i < leafNum; ++i) {
            data[i].weight = sc.nextInt();
        }
        str = sc.next();
        sc.close();

        int data1, data2, index1, index2;
        for (int i = 0; i < leafNum - 1; ++i) {
            data1 = data2 = Integer.MAX_VALUE;
            index1 = index2 = 0;
            for (int j = 0; j < leafNum + i; ++j) {
                if (data[j].weight < data1 && data[j].parent == -1) {
                    index2 = index1;
                    data2 = data1;
                    index1 = j;
                    data1 = data[j].weight;
                } else if (data[j].weight < data2 && data[j].parent == -1) {
                    index2 = j;
                    data2 = data[j].weight;
                }
            }
            data[index1].parent = leafNum + i;
            data[index2].parent = leafNum + i;
            data[leafNum + i].weight = data[index1].weight + data[index2].weight;
            data[leafNum + i].lchild = index1;
            data[leafNum + i].rchild = index2;
        }
    }

    public void print() {
        int[] id = new int[leafNum];
        char[][] mp = new char[leafNum][leafNum];
        for (int i = 0; i < leafNum; ++i) {
            int tmp = i;
            while (data[tmp].parent != -1) {
                int last = tmp;
                tmp = data[tmp].parent;
                if (data[tmp].lchild == last) {
                    mp[i][id[i] ++] = 'l';
                } else {
                    mp[i][id[i] ++] = 'r';
                }
            }
        }
        for (int i = 0; i < leafNum; ++i) {
            System.out.print(str.charAt(i) + ":");
            for (int j = id[i] - 1; j >= 0; --j) {
                System.out.print(mp[i][j] + " ");
            }
            System.out.println();
        }
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是Java实现哈夫曼树的代码和详细步骤: ```java import java.util.PriorityQueue; public class HuffmanTree { private Node root; private static class Node implements Comparable<Node> { private final char ch; private final int freq; private final Node left, right; Node(char ch, int freq, Node left, Node right) { this.ch = ch; this.freq = freq; this.left = left; this.right = right; } public boolean isLeaf() { return left == null && right == null; } public int compareTo(Node that) { return this.freq - that.freq; } } public HuffmanTree(char[] chars, int[] freqs) { PriorityQueue<Node> pq = new PriorityQueue<>(); for (int i = 0; i < chars.length; i++) { pq.offer(new Node(chars[i], freqs[i], null, null)); } while (pq.size() > 1) { Node left = pq.poll(); Node right = pq.poll(); Node parent = new Node('\0', left.freq + right.freq, left, right); pq.offer(parent); } root = pq.poll(); } private void buildCode(String[] st, Node x, String s) { if (!x.isLeaf()) { buildCode(st, x.left, s + '0'); buildCode(st, x.right, s + '1'); } else { st[x.ch] = s; } } public String[] buildCode() { String[] st = new String[256]; buildCode(st, root, ""); return st; } public static void main(String[] args) { char[] chars = {'a', 'b', 'c', 'd', 'e', 'f'}; int[] freqs = {45, 13, 12, 16, 9, 5}; HuffmanTree tree = new HuffmanTree(chars, freqs); String[] code = tree.buildCode(); for (int i = 0; i < chars.length; i++) { System.out.println(chars[i] + ": " + code[chars[i]]); } } } ``` 步骤如下: 1.定义一个Node类,表示哈夫曼树的节点,包含字符、频率、右子节点等信息。 2.定义HuffmanTree类,包含一个Node类型的根节点。 3.在HuffmanTree类中定义一个Node类的比较器,用于构建哈夫曼树时的优先队列排序。 4.在HuffmanTree类中定义一个构造函数,接收字符数组和频率数组作为参数,用于构建哈夫曼树。 5.在构造函数中,先将所有节点加入优先队列中。 6.然后不断从优先队列中取出两个频率最小的节点,合并成一个新的节点,再将新节点加入优先队列中,直到队列中只剩下一个节点,即为根节点。 7.在HuffmanTree类中定义一个buildCode方法,用于生成每个字符的哈夫曼编码。 8.在buildCode方法中,递归遍历哈夫曼树,生成每个字符的编码。 9.在HuffmanTree类中定义一个main方法,用于测试。 10.在main方法中,定义字符数组和频率数组,创建HuffmanTree对象,调用buildCode方法生成编码,输出每个字符的编码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qing影

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值