无法正确创建二叉树?

时间:2011-05-06 02:34:55

标签: java binary-tree bitstring

我正在尝试使用Java通过管道传输到System.in的字符串输入构建二叉树。每当在字符串中遇到来自a-z的字母时,我正在创建一个内部节点(带有2个子节点)。每当在字符串中遇到0时,我正在创建外部节点(叶子)。该字符串是预先排序的,所以作为一个例子,如果我有一个输入,如:

  

abcd000e000

我应该制作以下二叉树

            a
           / \
          b   0
         / \
        c   e
       / \ / \
      d  00   0
     / \
    0   0

至少这是我认为我应根据作业细节制作的(在下面的链接中)。我们还为整个计划提供了样本输入和输出:

输入

  

A0
  0
  A00
  ab000

输出

  

树1:
  无效!
  树2:
  身高:-1
  路径长度:0
  完成:是的   后序:
  树3:
  身高:0
  路径长度:0
  完成:是的   后序:a   树4:
  身高:1
  路径长度:1
  完成:是的   后序:ba

我正在尝试实现一个程序,它将使用Java为我做这个,但我不认为我正在使用二进制树。到目前为止,我已经提供了我已经提出的代码,并在上面的注释中详细说明了每个方法在调试时到目前为止遇到的问题。如果需要更多上下文,以下链接详细说明了整个任务以及最终目标应该是什么(构建二叉树只是第一步,但我坚持下去):

Link to Assignment

import java.io.*;

// Node
class TreeNode {
    char value;
    TreeNode left;
    TreeNode right;
}

// Main class
public class btsmall {
    // Global variables
    char[] preorder = new char[1000];
    int i = 0;

    // Main method runs gatherOutput
    public static void main(String[] args) throws IOException {
        new btsmall().gatherOutput();
    }

    // This takes tree as input from the gatherOutput method
    // and whenever a 0 is encountered in the preorder character array
    // (from a string from System.in) a new external node is created with
    // a value of 0. Whenever a letter is encountered in the character
    // array, a new internal node is created with that letter as the value.
    //
    // When I debug through this method, the tree "appears" to be made
    // as expected as the tree.value is the correct value, though I 
    // can't check the tree.left or tree.right values while debugging
    // as the tree variable seems to get replaced each time the condition
    // checks restart.
    public void createTree(TreeNode tree) throws IOException {
        // Check that index is not out of bounds first
        if (i >= preorder.length) {
            i++;
        } else if (preorder[i] == '0') {
            tree = new TreeNode();
            tree.value = '0';
            tree.left = tree.right = null;
            i++;                
        } else {
            tree = new TreeNode();
            tree.value = preorder[i];
            i++;
            createTree(tree.left);
            createTree(tree.right);
        }
    }

    // Supposed to print out contents of the created binary trees.
    // Intended only to test that the binary tree from createTree()
    // method is actually being created properly.
    public void preorderTraversal(TreeNode tree) {
        if (tree != null) {
            System.out.println(tree.value + " ");
            preorderTraversal(tree.left);
            preorderTraversal(tree.right);
        }
    }

    // Reads System.in for the Strings used in making the binary tree
    // and is supposed to make a different binary tree for every line of input
    //
    // While debugging after the createTree method runs, the resulting tree variable
    // has values of tree.left = null, tree.right = null, and tree.value has no value
    // (it's just a blank space).
    //
    // This results in preorderTraversal printing out a single square (or maybe the square
    // is some character that my computer can't display) to System.out instead of all 
    // the tree values like it's supposed to...
    public void gatherOutput() throws IOException {
        InputStreamReader input = new InputStreamReader(System.in); 
        BufferedReader reader = new BufferedReader(input);

        String line = null;
        TreeNode tree = new TreeNode();
        while ((line = reader.readLine()) != null) {
            preorder = line.toCharArray();
            createTree(tree);
            preorderTraversal(tree);
            i = 0;
        }
    }
}

任何人都可以帮我正确构建二叉树并指出我做错了会导致我目前得到的输出吗?我至少走在正确的轨道上吗?任何提示?

感谢。

编辑:b 这是“square”输出的图片(这是在Eclipse中)。

4 个答案:

答案 0 :(得分:3)

您的createTree()方法...不会创建树。

您永远不会将内部节点附加到任何内容...您只需创建它们,插入值,然后将它们传递给下一个createTree()调用(执行相同操作)。

答案 1 :(得分:2)

快速修复可以是对createTree(..)方法的简单修改,

public void createTree(TreeNode tree) throws IOException {
    // Check that index is not out of bounds first
    if (i >= preorder.length) {
        i++;
    } else if (preorder[i] == '0') {
        tree.value = '0';
        tree.left = tree.right = null;
        i++;                
    } else {
        tree.value = preorder[i];   
        i++;
        tree.left = new TreeNode();
        createTree(tree.left);
        tree.right = new TreeNode();
        createTree(tree.right);
    }
}

请注意,您在此方法中创建了TreeNode,而它已作为参数传递。所以,你根本没有使用相同的东西。无论你做了什么都不是原来TreeNode通过的。

NB: 不争论二叉树的正确性。只需解决手头的问题。这可能有助于OP。

答案 2 :(得分:1)

  

但我认为我没有正确制作二叉树

是的,这是不正确的。在二叉树中,一个子树比当前元素“少”,另一个子树是“更多”。例如,您有“b”作为“c”和“e”的父级,而(如果遵循自然排序)“c”和“e”都是“更多”。

您需要在此过程中重新平衡您的树。

P.S。我不知道输入中的零意味着什么,但如果输入有限,则从排序序列构建二叉树的最简单方法是:

  1. 将整个序列加载到数组中
  2. 将中间元素作为根元素
  3. 以递归方式对根元素左侧和右侧的子数组重复步骤2
  4. <强>更新

    是的,正如其他一些答案所述,你需要有类似的东西:

        } else if (preorder[i] == '0') {
            TreeNode subTree = new TreeNode();
            subTree.value = '0';
            tree.rigth = subTree;
            i++;  
    

    然后将subTree传递给递归调用。

答案 3 :(得分:1)

我也看到了一个实施问题:

    while ((line = reader.readLine()) != null) {

似乎不是正确的停止条件。它将永远循环,因为如果你只按Enter键,line将不为null,而是一个空字符串。

这个更合适:

    while (!(line = reader.readLine()).equals("")) {