【问题标题】:Create a binary tree from a sorted array list从排序数组列表创建二叉树
【发布时间】:2017-03-31 10:54:16
【问题描述】:

我需要为大学作业的文本编写 Huffman 压缩程序。 练习分为多个点,其中一个是从给定的TreeNode类型的排序arrayList创建一个二叉树,这个类看起来像这样(我删除了方法体):

public class TreeNode implements Comparable<TreeNode>, Serializable {

    private byte value;

    private int frequency;

    private TreeNode left, right;

    /** Creates new TreeNode .. must get initialized with value */
    public TreeNode(byte value) {
        this(value, 0, null, null);
    }

    /** Creates new TreeNode with full init */
    public TreeNode(byte value, int frequency, TreeNode left, TreeNode right) {
        this.value = value;
        this.frequency = frequency;
        this.left = left;
        this.right = right;
    public void incFrequency()
    public int getFreq()
    public Byte getValue()
    public TreeNode getLeft()
    public TreeNode getRight() 
    public boolean isLeaf()
    public int getSubTreeSize() 
    public void toHeap(byte[] heap, int myIndex) 
    public void initLookup(long myCode, int myDepth, Map<Byte, BitCode> lookupTable)
    @Override
    public int compareTo(TreeNode o)
    @Override
    public String toString()
    public void printSubTree(PrintStream out, int tabs)
    public void write(BitStream bs)
    public static TreeNode read(BitStream bs)

}

我需要从 TreeNode 类型的 arrayList 创建一棵二叉树,arrayList 按值排序,因此我可以假设具有 smalles 值的元素位于索引位置 0。 树必须满足一个重要条件: 具有下一个较大值的元素需要附加到左侧,具有更大值的元素需要附加到右侧(树将始终构建在右侧)。

我解决这个问题的尝试是遍历列表,获取项目,然后将具有奇数索引的每个项目附加到前一个节点的左叶,并将每个具有偶数索引的项目附加到右叶。

有没有更优雅的方法来解决这个问题? (我不要求你为我做作业,但我可能需要一些想法)

编辑: 我需要保留 SortedList,因为它是练习规范的一部分

【问题讨论】:

  • 你的方法有效吗?根据您的描述,它听起来不像(尽管它非常接近会的东西),但是您问题中的措辞使它听起来像它确实有效。
  • @Dukeling 不行
  • 尝试在纸上画树,看看应该连接什么。您的方法只需稍作改动即可生效。

标签: java algorithm arraylist


【解决方案1】:

只是为了帮助你,你可以按照以下思路思考:

  1. 选择中间元素作为根节点
  2. 将数组列表一分为二 - 左边从 0 到 mid-1,右边从 mid+1 到 last
  3. 递归地重复步骤 1,直到数组中只剩下一个元素。
  4. 当只剩下一个元素时返回该元素。

编辑我的答案,因为我最初没有正确理解要求。

第一次编辑 - 你可以做这样的事情 - 0.如果没有元素,返回 1. 让第一个元素成为你的根。 2. 如果下一个元素作为左孩子存在,则制作它。 3. 递归调用函数,使其结果成为正确的孩子。

【讨论】:

  • 这将生成一个均匀分布的树,但我需要一棵树,它满足左侧较小元素和右侧较大元素的条件,因为该树位于 Hufmancompression 的代码表后面并且码字来自这棵树
  • 均匀分布的二叉搜索树的左侧元素较小,右侧元素较大。例如,如果您的数组是这样的 - 10, 15, 20, 25, 30。由上述逻辑生成的树将是 --- (10 -> 15) 25-> 30
  • OP 不想要二叉搜索树。正如我在问题中的描述,10、15、20、25、30 应该给出一棵以 10 为根的树,有 15 和 20 的孩子,20 应该有 25 和 30 的孩子。
【解决方案2】:

在头疼之后,我终于找到了解决这个问题的方法。

  1. 我遍历了 TreeNode 列表,
  2. 我从列表中删除了第一项并将其存储在一个名为“left”的临时变量中,我再次做了同样的事情并将其称为“right”,因为列表已排序,这将始终提供最大和第二大(就频率而言)列表的元素。
  3. 我在树中添加了一个新的 TreeNode,它的值为 0,频率是左右 TreeNode 的频率之和,以及在步骤中从列表中删除的左右左右 TreeNode 的频率之和2.
  4. 我再次对列表进行了排序。
  5. 只要树的大小超过 1 个元素,就会重复这些步骤。

我的代码如下所示:


private void initializeTree(List tree) {

do{

    TreeNode left = tree.remove(0);
    TreeNode right = tree.remove(0);

    tree.add(new TreeNode((byte)0, left.getFreq() + right.getFreq(), left, right));

    Collections.sort(tree);

}while(tree.size() > 1);

root = tree.get(0);
printTree(System.out);

}

方法print tree是一个静态方法,如果这个类只是将树打印到控制台,root变量是二叉树的根节点。

【讨论】:

    猜你喜欢
    • 2017-12-05
    • 1970-01-01
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    • 2021-05-21
    • 2016-02-24
    • 1970-01-01
    相关资源
    最近更新 更多