Input string to binary tree inorder traversal

huangapple go评论66阅读模式
英文:

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&lt;String&gt; queue = new LinkedList&lt;&gt;(); 
Stack&lt;String&gt; stack = new Stack&lt;&gt;(); 
String[] a = tree.split(&quot;&quot;); 
int i = 0;
while (i &lt; tree.length()) { // holds string&#39;s chars
queue.add(a[i]);
i = i + 1;
}
while (!queue.isEmpty()) { 
String b = queue.remove();
if (!b.equals(&quot;(&quot;)) {
stack.push(b); // stores closed brackets, number, &amp; letters
if (b.equals(&quot;)&quot;) &amp; !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 + &quot; &quot;);
/* 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 that root has a parent, so then return 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 have A()(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 it null, while the next information would serve for a right child.

  • ...

Some other remarks:

  • The Node class should not have a root member. Only the BinaryTree class should have that.

  • The BinaryTree class should not need parent (a tree has no parent), c (that should just be a local variable), r (?), nor even tree (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 its root.

  • strToTree should better return a new BinaryTree instance instead of a Node. 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 the BinaryTree class. It should just call the method with the same name on the Node class.

  • The inOrderTraverse method on the Node class should be static (it doesn't use the current node this).

  • 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&lt;Node&gt; stack = new Stack&lt;&gt;();
Stack&lt;Boolean&gt; sidestack = new Stack&lt;&gt;(); 
for (int i = 0; i &lt; input.length(); i++) {
char ch = input.charAt(i);
if (ch == &#39;)&#39;) {
if (input.charAt(i-1) != &#39;(&#39;) { // Exclude empty node 
stack.pop(); // This node has no more children to add
sidestack.pop();
}
} else if (ch != &#39;(&#39;) {
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 + &quot; &quot;);
inOrderTraverse(root.right);
}
}
// Demo
public static void main(String[] args) {
String input = &quot;G(Y(u)(5))(2()(t))&quot;;
BinaryTree tree = new BinaryTree(input);
tree.inOrderTraverse();
}
}

huangapple
  • 本文由 发表于 2023年5月6日 23:57:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76189838.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定