1

我正在尝试使用 Java 从通过管道传输到 System.in 的字符串输入构建二叉树。每当在字符串中遇到来自 az 的字母时,我都会创建一个内部节点(有 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 实现一个可以为我执行此操作的程序,但我认为我没有正确地制作二叉树。我已经提供了到目前为止我提出的代码,并在每种方法上方的注释中详细说明了到目前为止我在调试时遇到了什么麻烦。如果需要更多上下文,以下链接详细说明了整个分配以及最终目标应该是什么(构建二叉树只是第一步,但我坚持下去):

作业链接

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 这是“方形”输出的图片(这是在 Eclipse 中)。

4

4 回答 4

3

你的createTree()方法......不会创建一棵树。

您永远不会将内部节点附加到任何东西......您只需创建它们,插入值,然后将它们传递给下一个createTree()调用(它也是如此)。

于 2011-05-06T02:56:34.513 回答
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通过。

注意: 不争论二叉树的正确性。只要解决手头的问题。这可能对 OP 有所帮助。

于 2011-05-06T03:06:07.213 回答
1

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

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

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

PS我不知道输入中的零应该是什么意思,但是如果输入受到限制,从排序序列构建二叉树的最简单方法是:

  1. 将整个序列加载到数组中
  2. 将中间元素作为根元素
  3. 对根元素左右的子数组递归重复第2步

更新

是的,正如其他答案中所述,您需要具备以下条件:

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

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

于 2011-05-06T02:58:20.503 回答
1

我还看到一个实现问题:

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

似乎不是正确的停止条件。它将永远循环,因为如果您按回车键,则 line 不会为空,而是一个空字符串。

这个比较适合:

    while (!(line = reader.readLine()).equals("")) {
于 2011-05-06T03:15:04.737 回答