英文:
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
root
variable 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 thatroot
has a parent, so thenreturn root
is 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
Node
class should not have aroot
member. Only theBinaryTree
class should have that. -
The
BinaryTree
class 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
. -
strToTree
should better return a newBinaryTree
instance 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
inOrderTraverse
method you have on theBinaryTree
class. It should just call the method with the same name on theNode
class. -
The
inOrderTraverse
method on theNode
class should be static (it doesn't use the current nodethis
). -
Using a
Queue
is 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();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论