英文:
Input string to binary tree inorder traversal
问题
I am creating a program that accepts the bracket notation of a binary tree, and then provides various functions such as inorder traversal.
For the sake of this example: Input is G(Y(u)(5))(2(t)).
When traversing through the tree, my code only returns Y G u , but it should return u Y 5 G 2 t.
My main method provides a GUI for the user to enter the binary tree string. I have a separate class that constructs the binary tree and contains a private class that constructs each node.
I have reviewed my code, but can't quite figure out what the issue is.
public class BinaryTree {
Node root;
Node parent;
Character c;
String r;
String tree;
public BinaryTree(String tree) { // constructor
this.tree = tree;
}
public Node strToTree(String tree) {
Queue<String> queue = new LinkedList<>();
Stack<String> stack = new Stack<>();
String[] a = tree.split("");
int i = 0;
while (i < tree.length()) { // holds string's chars
queue.add(a[i]);
i = i + 1;
}
while (!queue.isEmpty()) {
String b = queue.remove();
if (!b.equals("(")) {
stack.push(b); // stores closed brackets, number, & letters
if (b.equals(")") && !stack.isEmpty()) {
stack.pop(); // parenthesis
String e = stack.pop(); // character
String f = stack.lastElement();
c = e.charAt(0);
char g = f.charAt(0);
root = new Node(c);
parent = new Node(g);
if (parent.left == null) {
parent.left = root;
parent = parent.left;
} else
parent.right = root;
}
}
}
return root;
}
public void inOrderTraverse(String tree) {
Node root = new Node(tree.charAt(0));
Node left = new Node(tree.charAt(2));
Node right = new Node(tree.charAt(4));
getString(tree);
root.inOrderTraverse(left);
root.inOrderTraverse(root);
root.inOrderTraverse(right);
root.inOrderTraverse(left.left); // testing case
}
static class Node {
char data;
Node left;
Node right;
Node root;
private Node(char data) { // constructor
this.data = data;
left = null;
right = null;
}
public void inOrderTraverse(Node root) {
if (root == null)
return;
/* first recur on left child */
inOrderTraverse(root.left);
// (root.left);
/* then print the data of node */
System.out.print(root.data + " ");
/* now recur on right child */
inOrderTraverse(root.right);// root.right);
}
}
}
(Note: I've made some corrections to your code to fix syntax and logic issues.)
英文:
I am creating a program that accepts the bracket notation of a binary tree, and then provides various functions such as inorder traversal.
For the sake of this example: Input is G(Y(u)(5))(2(t)).
When traversing through the tree, my code only returns Y G u , but it should return u Y 5 G 2 t.
My main method provides a GUI for the user to enter the binary tree string. I have a separate class that constructs the binary tree and contains a private class that constructs each node.
I have reviewed my code, but can't quite figure out what the issue is.
I have checked out Geeks for Geeks as well as YouTube videos, but I am having issues grasping the concept.
public class BinaryTree {
Node root;
Node parent;
Character c;
String r;
String tree;
public BinaryTree(String tree) { // constructor
this.tree = tree;
}
public Node strToTree(String tree) {
Queue<String> queue = new LinkedList<>();
Stack<String> stack = new Stack<>();
String[] a = tree.split("");
int i = 0;
while (i < tree.length()) { // holds string's chars
queue.add(a[i]);
i = i + 1;
}
while (!queue.isEmpty()) {
String b = queue.remove();
if (!b.equals("(")) {
stack.push(b); // stores closed brackets, number, & letters
if (b.equals(")") & !stack.isEmpty()) {
stack.pop(); // parenthesis
String e = stack.pop(); // character
String f = stack.lastElement();
c = e.charAt(0);
char g = f.charAt(0);
root = new Node(c);
parent = new Node(g);
if (parent.left == null) {
parent.left = root;
parent = parent.left;
} else
parent.right = root;
}
}
}
return root;
}
public void inOrderTraverse(String tree) {
Node root = new Node(tree.charAt(0));
Node left = new Node(tree.charAt(2));
Node right = new Node(tree.charAt(4));
getString(tree);
root.inOrderTraverse(left);
root.inOrderTraverse(root);
root.inOrderTraverse(right);
root.inOrderTraverse(left.left); // testing case
}
static class Node {
char data;
Node left;
Node right;
Node root;
private Node(char data) { // constructor
this.data = data;
left = null;
right = null;
}
public void inOrderTraverse(Node root) {
if (root == null)
return;
/* first recur on left child */
inOrderTraverse(root.left);
// (root.left);
/* then print the data of node */
System.out.print(root.data + " ");
/* now recur on right child */
inOrderTraverse(root.right);// root.right);
}
}
}
答案1
得分: 0
在strToTree中的逻辑不正确。存在一些问题:
-
每次处理“)”时,“root”变量都会被新的节点覆盖,因此失去了先前的内容。
-
当遇到“)”时,不能正确创建两个节点。
-
可能在空栈上执行
stack.lastElement()。 -
通过设置
parent.right = root;,你承认root有一个父节点,因此return root不返回根节点。 -
if (parent.left == null) {可能不是检测左子树必须接收新子树的正确方式。考虑到输入可能是A()(C),表示“A”没有左子树,但确实有右子树(C)。你需要以某种方式注册()是左子树的输入,保持它为null,而下一个信息将用于右子树。 -
...
其他注意事项:
-
Node类不应该有root成员。只有BinaryTree类应该有。 -
BinaryTree类不应该需要parent(树没有父节点),c(应该是局部变量),r(?),甚至不需要tree(因为那是应立即转换为树本身的字符串输入 -- 无需保留它)。因此,树唯一需要的属性是其root。 -
strToTree最好返回一个新的BinaryTree实例,而不是一个Node。因此,它应该是一个静态方法,或者更好地说,是类的构造函数。 -
我看不到你在
BinaryTree类上有一个名为inOrderTraverse的方法的意图。它应该只调用Node类上同名的方法。 -
Node类上的inOrderTraverse方法应该是静态的(它不使用当前节点this)。 -
使用
Queue有些过度。你可以只迭代输入字符串的字符。 -
为了跟踪输入字符串中下一个标记是关于左子树还是右子树,你还可以为每个在栈上的节点堆叠一个布尔值。例如,你可以有一个<Node,Boolean>对的堆栈,或者只是两个协同操作的堆栈。
英文:
The logic in strToTree is not correct. Some of the issues:
-
Every time a ")" is processed the
rootvariable is overwritten with a new node -- so losing whatever was there before. -
It cannot be right that you would have to create two nodes whenever a ")" is encountered.
-
stack.lastElement()may be executed on an empty stack... -
By setting
parent.right = root;you admit thatroothas a parent, so thenreturn rootis not returning the root. -
if (parent.left == null) {might not be the right way to detect that the left child has to receive the new child. Consider that an input might haveA()(C)to indicate that "A" has no left child, but does have a right child (C). You would need to somehow register that()was the input for the left child, keeping itnull, while the next information would serve for a right child. -
...
Some other remarks:
-
The
Nodeclass should not have arootmember. Only theBinaryTreeclass should have that. -
The
BinaryTreeclass should not needparent(a tree has no parent),c(that should just be a local variable),r(?), nor eventree(as that is string input that should immediately be converted to the tree itself -- there is no need to persist that). So the only property a tree needs is itsroot. -
strToTreeshould better return a newBinaryTreeinstance instead of aNode. So it should be a static method, or even better, a constructor for the class. -
I don't see what you intended to do with the
inOrderTraversemethod you have on theBinaryTreeclass. It should just call the method with the same name on theNodeclass. -
The
inOrderTraversemethod on theNodeclass should be static (it doesn't use the current nodethis). -
Using a
Queueis overkill. You can just iterate the characters of the input string. -
To keep track of whether the next token in the input string is about a left or a right child, you could also stack a boolean for each node that is on the stack. You could for instance have a stack of pairs <Node, Boolean>, or just two stacks that operate in tandem.
Here is an overhaul of your code:
public class BinaryTree {
Node root;
public BinaryTree(String input) {
root = null;
Stack<Node> stack = new Stack<>();
Stack<Boolean> sidestack = new Stack<>();
for (int i = 0; i < input.length(); i++) {
char ch = input.charAt(i);
if (ch == ')') {
if (input.charAt(i-1) != '(') { // Exclude empty node
stack.pop(); // This node has no more children to add
sidestack.pop();
}
} else if (ch != '(') {
Node node = new Node(ch);
if (stack.isEmpty()) {
root = node;
} else {
boolean side = sidestack.peek();
if (side) {
stack.peek().right = node;
} else {
stack.peek().left = node;
}
sidestack.pop();
sidestack.push(!side); // Toggle child
}
stack.push(node);
sidestack.push(false);
}
}
}
public void inOrderTraverse() {
Node.inOrderTraverse(root);
}
static class Node {
char data;
Node left;
Node right;
private Node(char data) { // constructor
this.data = data;
left = null;
right = null;
}
static public void inOrderTraverse(Node root) {
if (root == null)
return;
inOrderTraverse(root.left);
System.out.print(root.data + " ");
inOrderTraverse(root.right);
}
}
// Demo
public static void main(String[] args) {
String input = "G(Y(u)(5))(2()(t))";
BinaryTree tree = new BinaryTree(input);
tree.inOrderTraverse();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论