从排序数组列表中创建二叉树

时间:2017-03-31 10:54:16

标签: java algorithm arraylist

我需要为大学作业编写一个Huffman压缩文本。 练习分为多个点,其中一个是从给定的排序arrayList创建一个二叉树,类型为TreeNode,这个类看起来像这样(我删除了方法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。 树必须满足一个重要条件: 具有下一个较大值的元素需要附加在左侧,而具有更大值的元素需要附加到右侧(树将始终构建在右侧)。

我尝试解决这个问题的方法是遍历列表,获取项目,然后将每个带有奇数索引的项目附加到上一个节点的左侧离开,并将每个项目带有偶数索引到右侧离开。 / p>

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

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

2 个答案:

答案 0 :(得分:0)

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

  1. 选择中间元素作为根节点
  2. 将数组列表拆分为两个 - 从0开始到中间1,从中间+ 1到最后开始
  3. 递归重复步骤1,直到阵列中只剩下一个元素。
  4. 只留下一个元素时返回该元素。
  5. 编辑我的答案,因为我最初没有正确理解这些要求。

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

答案 1 :(得分:0)

经过一番头痛后,我终于找到了解决这个问题的方法。

  1. 我遍历了TreeNode列表,
  2. 我从列表中删除了第一个项目,并将其存储在一个名为“left”的临时变量中,我再次做同样的事情并称之为“正确”,因为列表已经排序,这将始终提供最大和第二大(在频率方面)列表的元素。
  3. 我在树中添加了一个新的TreeNode,其值为0,频率为左右和左右TreeNode的频率之和,左右两侧的左右分别从步骤中删除2。
  4. 我再次对列表进行了排序。
  5. 只要树的大小超过1个元素,就会重复这些步骤。
  6. 我的代码如下所示:

    
    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);
    

    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树是一个静态方法,如果这个类只是将树打印到控制台,则根变量是二叉树的根节点。