Recursive toString binary tree output - java

So I want my printout of my binary tree to read like [A B C D E F] but I keep ending up with an extra space and I can't use subString to remove it. What is the best way to approach this?
public String toStringInOrder() {
output = "";
output += printInOrder(root);
if(output.length() < 1) {
return "[]";
} else {
return "[" + output.substring(0, output.length() - 1) + "]";
}
}
private String printInOrder(Node current) {
if(current != null) {
printInOrder(current.left);
output += current.value + " ";
printInOrder(current.right);
}
return output;
}

If your only concern is removing the extra space at the end you could replace:
return "[" + output.substring(0, output.length() - 1) + "]";
with:
return "[" + output.Trim() + "]";
Another approach I might take is filling a List with the ordered values, and then you can have a greater control of how you format the ordered values as a string.

If you can't use substring or similars, do a "look for maximum node" search (cheap log(n) operation), save that node and add an if statement on your output additions that checks if the node whose info has to be added isn't the last one. In that case, add the value without the space.
Node last = max(root);
private Node max(Node x){
if (x.right == null)
return x;
return max(x.right);
}
private String printInOrder(Node current) {
if(current != null) {
printInOrder(current.left);
if(!current.equals(last))
output += current.value + " ";
else
output += current.value;
printInOrder(current.right);
}
return output;
}

I discovered the answer I needed after some diagramming and trial and error.
private String printPreOrder(Node current) {
if (current != null) {
output += current.value;
if (current.left != null) output += " ";
printPreOrder(current.left);
if (current.right != null) output += " ";
printPreOrder(current.right);
}
return output;
}
Some changes to the inOrder and postOrder garners similar results. Thanks to all for the help!

Related

building a string recursively in java using a Binary search trees data

I am trying to build a string recursively but the method returns the string before the recursive method is done.
What code should do is when toStringHelper is called it should create a string of all of the elements in the binary search tree in order. I can do this with a print statement with the given code but don't know how to make it into a string that gets returned.
protected static String toStringHelper(BSTNode current, String result) {
if (current != null) {
toStringHelper(current.getLeft(), result);
result += current.getData().toString() + "\n";
toStringHelper(current.getRight(), result);
}
return result;
}
Can't you just append directly to result? It should build the same.
protected static String toStringHelper(BSTNode current, String result) {
if (current != null) {
if(current.getLeft() != null) result += toStringHelper(current.getLeft(), result);
result += current.getData().toString() + "\n";
if(current.getRight() != null) result += toStringHelper(current.getRight(), result);
}
return result;
}
Actually String result argument is not needed . You can check below code .
protected static String toStringHelper(BSTNode current)
{
if (current == null)
{
return "";
}
String result="";
result += toStringHelper(current.getLeft());
result += current.getData().toString() + "\n";
result += toStringHelper(current.getRight());
return result;
}
This is how it is called from main()
BSTNode root = new BSTNode();
root.setData("Root");
root.setLeft(new BSTNode(null, null, "Left"));
root.setRight(new BSTNode(null, null, "Right"));
String res = toStringHelper(root);
System.out.println("Res is " + res);
Here is the o/p
Res is Left
Root
Right

how to expand a huffman node after compression

I collapsed all of huffman nodes into one node and trying to build a tree by that node and make a code for each character(huffman leaf) but I can't manage it
I have already tried to write a method but it didn't work because it stops when the first code is created for the first character
this is my method:
public String createKey(Node node,String s){
if(node.right==null&&node.left==null) {
hashMap.put(node, s);
s="";
}
if (node.left!=null)
return createKey(node.left,s+"0");
if(node.right!=null)
return createKey(node.right,s+"1");
return s;
}
It's usually best to have a single return statement than to have multiple return statements. Your code doesn't visit right nodes because you are returning before that code is ever reached. Something like this will visit every node. You might have to play with the formatting of the results a bit.
public String createKey(Node node,String s){
if(node.right == null && node.left == null) {
hashMap.put(node, s);
s="";
}
if (node.left != null)
s += createKey(node.left, s + "0");
if(node.right != null)
s += createKey(node.right, s + "1");
return s;
}
Something like this would also work and maybe be easier to format results:
public String createKey(Node node,String s){
if(node.right == null && node.left == null) {
hashMap.put(node, s);
s="";
}
else if (node.left != null && node.right != null)
s = createKey(node.left, s + "0") + " " + createKey(node.right, s + "1");
else if (node.left != null)
s = createKey(node.left, s + "0");
else if(node.right != null)
s = createKey(node.right, s + "1");
return s;
}

Print a binary search tree as a single string

There's a practice problem that I've been working on that's been confusing me.
Define a function treeLevelOrder which satisfies the following claim:
If Q is a binary search tree of integers, then treeLevelOrder(Q) is the String representation of the contents of Q according to their level in the tree.
We get this tree as an example
9
/ \
5 16
/ \ / \
1 7 12 19
The value of the expression treeLevelOrder(Q) in this case would be
"[9,5,16,1,7,12,19]".
I've seen similar problems, but they don't follow the same format that I'm looking for, wanting to print by level order or as ordered tuples. Here's some sample code I've been working on:
private String treeLevelOrder(Node Q)
{
if (Q.left == null && Q.right == null)
return "[" + Q.datum + "]";
else if (Q.left == null && Q.right != null)
return "[" + Q.datum + ", "+Q.right.datum+"]" + treeLevelOrder(Q.right);
else if (Q.left !=null && Q.right == null)
return"[" + Q.datum + ", "+Q.left.datum+", *]"+ treeLevelOrder(T.left);
else
return "[" + Q.datum + ", "+Q.left.datum+", "+Q.right.datum+"]" +
treeLevelOrder(Q.left) + treeLevelOrder(Q.right);
}
Any assistance would be helpful.
EDIT: Okay, so I've been experimenting with the level order example at Geeks for Geeks, thank you curlyBraces, that would be closer to what I'm looking for, though I can't figure out to make it return a string. Here's the code they use:
/* function to print level order traversal of tree*/
void printLevelOrder()
{
int h = height(root);
int i;
for (i=1; i<=h; i++)
printGivenLevel(root, i);
}
/* Compute the "height" of a tree -- the number of
nodes along the longest path from the root node
down to the farthest leaf node.*/
int height(Node root)
{
if (root == null)
return 0;
else
{
/* compute height of each subtree */
int lheight = height(root.left);
int rheight = height(root.right);
/* use the larger one */
if (lheight > rheight)
return(lheight+1);
else return(rheight+1);
}
}
/* Print nodes at the given level */
void printGivenLevel (Node root ,int level)
{
if (root == null)
return;
if (level == 1)
System.out.print(root.data + ", ");
else if (level > 1)
{
printGivenLevel(root.left, level-1);
printGivenLevel(root.right, level-1);
}
}
Any ideas?
Here's an implementation using while loop and two queues to keep track of all the nodes:
public String treeLevelOrder(Node root) {
StringBuilder result = new StringBuilder("");
Queue<Node> current = new LinkedList<>();
Queue<Node> other = new LinkedList<>();
if(root != null)
current.add(root);
while(!current.isEmpty()) {
while(!current.isEmpty()) {
Node node = current.remove();
result.append(",");
result.append(node.datum);
// adding children to the other queue
if(node.left != null)
other.add(node.left);
if(node.right != null)
other.add(node.right);
}
// swapping the queues
Queue<Node> temp = current;
current = other;
other = temp;
}
// building final string
if(result.length() == 0)
result.append("[");
else
result.setCharAt(0,'[');
result.append("]");
return result.toString();
}

Binary Node Tree, wrong father and sons

I'm having a hard time printing the following tree:
----------t1:----------
tree:(((1),2,(3)),4,((5),6,(7,(8))))
----------t2:----------
tree:(((1),2,((3),4)),5,(6,(7,(8))))
----------t3:----------
tree:((1),2,(3,(4,(5,(6,(7,(8)))))))
----------t4:----------
tree:((((((((1),2),3),4),5),6),7),8)
where "father" have no parentheses and each "son" has a bracket depends on the depth,the picture are the trees with depth.
here is my code:
private String toString(String acc,int length){
if (left != null)
acc =left.toString(acc, length + 1)+")"+",";
// Adding two spaces 'length' times
for (int i = 0; i < length; i++) {
acc +="";
}
// adding the object data and new space
acc += this.data.toString();
if (right != null)
acc = "("+right.toString(acc, length + 1);
return acc;
}
public String toString() {
return "("+toString("", 0)+")";
}
which instead prints:
----------t1:----------
tree:(((((1),23),45),678)
----------t2:----------
tree:(((((1),23),4),5678)
----------t3:----------
tree:(((((((1),2345678)
----------t4:----------
tree:(1),2),3),4),5),6),7),8)
in the added picture, the tree is demonstrated with depth
Actually, every node has an opening and closing parenthesis. As Stefan commented, you don't need the depth. Here's the code:
public String toString() {
String out = "(";
if (this.left != null) {
out += left.toString() + ",";
}
out += this.data;
if (this.right != null) {
out += "," + right.toString();
}
return out + ")";
}

How to avoid NULLs in String representation of Binary Search Tree?

As a programming exercise I need to rewrite some existing methods and classes that make up a binary tree. (The method signatures and constructors have to stay the same). Somehow I don't really seem to understand what I have done here.
Does the toString method have to public because it overwrites the Object class's toString method? And how can I avoid the nulls from being returned?
Here is the code I have come to so far:
Tree Class
Node root = null;
void addNode(int val) {
Node newNode = new Node(val);
root = newNode.addNode(root, val);
}
Node Class
Node(int val) {
val = val;
left = null;
right = null;
}
Node addNode(Node focusNode, int newNodeVal) {
if (focusNode == null)
return this;
if (newNodeVal == focusNode.val)
return focusNode;
if (newNodeVal < focusNode.val)
focusNode.left = this.addNode(focusNode.left, newNodeVal);
else
focusNode.right = this.addNode(focusNode.right, newNodeVal);
return focusNode;
}
public String toString() {
return this.left + " " + this.val + " " + this.right;
}
Use a StringBuilder to store the String representation of the node and append the data of the children nodes only in the specific node is not null. Here's an example using infix navigation on the nodes:
public String toString() {
StringBuilder sb = new StringBuilder();
if (this.left != null) {
sb.append(this.left);
sb.append(' ');
}
sb.append(this.val);
if (this.right != null) {
sb.append(' ');
sb.append(this.right);
}
return sb.toString();
}
public String toString() {
if(this.left==null){
return this.val + this.right;
} else if (this.right==null){
return this.left + this.val;
} else if (this.left == null && this.right == null){
return "";
} else {
return this.left + " " + this.val + " " + this.right;
}
}
You assign your nodes to null to start, and your toString method assumes that they have been altered. Imagine a tree where you added 5, then 3. Then called toString on the tree. It will try to print the node, 5 is the value, left is 3, right is null. When you try to call
return this.left + " " + this.val + " " + this.right;
You are saying to print
3 5 NULL
You can initialize left and right with an empty Node object (with no val) and when you print it you will see null as the val of an empty Node:
Node(Integer val) {
this.val = val;
left = new Node(null);
right = new Node(null);
}
This only works if you make val an Integer.
There is also a bug in your code:
val = val will leave this.val untouched. You have to use this.val = val;
toString() is overridden not overwritten. It has to return a String and you can't really avoid nulls if your Node is a leaf.
What you can do is writing toString() in a way it can be meaningful to have a null as val like this:
public String toString() {
return "#{val = " + val + ", left = " + left + ", right = " + right + "}"
}
Please note that this will traverse your tree recursively so to print your tree you only have to call root.toString().

Categories

Resources