Java 从已排序的数组列表创建二叉树

Java 从已排序的数组列表创建二叉树,java,algorithm,arraylist,Java,Algorithm,Arraylist,我需要为大学作业的文本编写一个哈夫曼压缩程序。 这个练习分为多个点,其中一个点是从一个给定的TreeNode类型的排序arrayList创建一个二叉树,这个类看起来像这样,我删除了boddies方法: public class TreeNode implements Comparable<TreeNode>, Serializable { private byte value; private int frequency; private TreeNod

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

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,因为它是练习规范的一部分,只是为了帮助您,您可以按照以下思路思考:

选择中间的元素作为根节点 将数组列表分成两部分-从0到1中间向左,从1中间向右,直到最后 递归地重复步骤1,直到数组中只剩下一个元素。 当只剩下一个元素时返回该元素。 编辑我的答案,因为我最初没有正确理解需求

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

我头痛了一会儿,终于找到了解决这个问题的办法

我反复浏览了TreeNode的列表, 我从列表中删除了第一项并将其存储在一个名为left的tempoary变量中,我再次做了同样的事情并将其称为right,因为列表是排序的,这将始终提供列表中频率元素的最大值和第二大值。 我向树中添加了一个新的TreeNode,它的值为0,频率为在步骤2中从列表中删除的左、左、右TreeNode和左、右TreeNode的频率之和。 我又把名单排序了一遍。 只要树的大小大于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是一个静态方法,如果这个类只是将树打印到控制台,根变量是二叉树的根节点。

它将生成一个均匀分布的树,但是我需要一个树,它满足以下条件:较小的元素在左边,较大的元素在右边,因为树位于Hufman压缩的代码表的后面,并且来自这个树的码字均匀分布的二叉搜索树在左边有较小的元素,在右边有较大的元素。例如,如果您的数组是这样的-10、15、20、25、30。由上述逻辑生成的树将是-10->15 25->30OP,不需要二进制搜索树。正如我在问题中所描述的,10,15,20,25,30应该给出一棵以10为根的树,有15和20个孩子,20应该有25和30个孩子。你的方法有效吗?根据你的描述,这听起来不太像,尽管它与可能的东西非常接近,但你问题中的措辞让它听起来像是起作用了。@Dukeling它不起作用。试着在纸上画一棵树,看看你应该连接什么。你的方法只需要稍微改变一下就行了。