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 + ")";
}
Related
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();
}
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!
I am trying ti implement the insert method of the Patricia Trie data structure but I have the feeling I wrote to many code lines. Please can someone tell me where can I call the method insert(TrieNode nodeRoot, String s) rekursiv?
Code:
private void insert(TrieNode nodeRoot, String s) {
int len1 = nodeRoot.value.length();
int len2 = s.length();
int len = Math.min(len1, len2);
for (int index = 0; index < len; index++) {
if (s.charAt(index) != nodeRoot.value.charAt(index)) {
// In case the both words have common substrings and after the
// common substrings the words are split.
String samesubString = s.substring(0, index);
String substringSplit1 = nodeRoot.value.substring(index);
String substringSplit2 = s.substring(index);
if (!samesubString.isEmpty()) {
nodeRoot.value = samesubString;
}
TrieNode nodeLeft = new TrieNode(substringSplit1);
nodeLeft.isWord = true;
TrieNode nodeRight = new TrieNode(substringSplit2);
nodeRight.isWord = true;
if (nodeRoot.getNext() != null && !nodeRoot.getNext().isEmpty()) {
checkTheValieAvialable(nodeRoot, s, nodeRight);
} else {
nodeRoot.next.add(nodeLeft);
nodeRoot.next.add(nodeRight);
for (TrieNode subword : nodeRoot.getNext()) {
System.out.println(nodeRoot.getValue() + "---"
+ subword.getValue());
}
}
break;
} else if (index == (s.length() - 1)
|| index == (nodeRoot.value.length() - 1)) {
// In case the node just needs one path since one word is
// substring of the other.
// For example (aba and abac)
if (len1 > len2) {
// root value is longer
System.out.println("root value is longer");
String samesubString = nodeRoot.value.substring(0,
index + 1);
String different = nodeRoot.value.substring(index + 1);
if (nodeRoot.getNext() != null
&& !nodeRoot.getNext().isEmpty()) {
for (TrieNode subword : nodeRoot.getNext()) {
String subword2 = subword.getValue();
boolean contains = different.contains(subword2);
if (contains) {
String[] split = different.split(subword2);
TrieNode leaf1 = new TrieNode(split[1]);
leaf1.isWord = true;
subword.next.add(leaf1);
System.out.println("Test.");
}
}
} else {
String substringSplit1 = nodeRoot.value.substring(index + 1);
nodeRoot.value = samesubString;
TrieNode leaf = new TrieNode(substringSplit1);
leaf.isWord = true;
nodeRoot.next.add(leaf);
for (TrieNode subword : nodeRoot.getNext()) {
System.out.println(nodeRoot.getValue() + "---"
+ subword.getValue());
}
}
String substringSplit1 = nodeRoot.value
.substring(index + 1);
nodeRoot.value = samesubString;
nodeRoot.isWord = true;
TrieNode leaf = new TrieNode(substringSplit1);
leaf.isWord = true;
nodeRoot.next.add(leaf);
for (TrieNode subword : nodeRoot.getNext()) {
System.out.println(nodeRoot.getValue() + "---"
+ subword.getValue());
}
} else {
// new inserted string value is longer. For example (abac and aba).
System.out.println("instered is longer");
String samesubString = s.substring(0, index + 1);
String different = s.substring(index + 1);
if (nodeRoot.getNext() != null
&& !nodeRoot.getNext().isEmpty()) {
for (TrieNode subword : nodeRoot.getNext()) {
String subword2 = subword.getValue();
boolean contains = different.contains(subword2);
if (contains) {
String[] split = different.split(subword2);
TrieNode leaf1 = new TrieNode(split[1]);
leaf1.isWord = true;
subword.next.add(leaf1);
System.out.println("Test.");
}
}
} else {
String substringSplit1 = s.substring(index + 1);
s = samesubString;
TrieNode parentLeaf = new TrieNode(s);
parentLeaf.isWord = true;
TrieNode leaf = new TrieNode(substringSplit1);
leaf.isWord = true;
nodeRoot.next.add(leaf);
for (TrieNode subword : nodeRoot.getNext()) {
System.out.println(nodeRoot.getValue() + "---"
+ subword.getValue());
}
}
}
} else {
System.out.println("They are the same - " + index);
}
}
}
TrieNode class:
package patriciaTrie;
import java.util.ArrayList;
public class TrieNode {
ArrayList<TrieNode> next = new ArrayList<TrieNode>();
String value;
boolean isWord;
TrieNode(String value){
this.value = value;
}
public ArrayList<TrieNode> getNext() {
return next;
}
public void setNext(ArrayList<TrieNode> next) {
this.next = next;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
While using recursion please consider the steps:
Base condition
Logic (if any)
Recursive call.
Ex. for factorial of number:
int fact(int n)
{
if(n==0 || n==1)
return 1; // Base condition
return n * fact(n-1); // Recursive call
}
Applying the same concept in Trie:
base condition is: while traversing through a path, if we have reached leaf, current string is not in trie, then create a new edge or node and add remaining character to it.
Recursively call the insert if we have found a matching node. And if a matching node doen't exist create a new path with common parent.
You can take help from link : http://www.geeksforgeeks.org/trie-insert-and-search/
The best way to approach to problem recursively is to identify base condition in a problem.
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().
I need to print out a QuadTree. The problem is that I don't know how to implement an incrementing shift in order to be able to visualize the tree structure.
Currently I just see each level of nodes at a new line. However, it's complicated to use this visualization for working with a tree.
#Override public String toString() {
StringBuilder result = new StringBuilder();
String NEW_LINE = System.getProperty("line.separator");
String SHIFT = System.getProperty(" ");
if (_children != null) {
String content = "";
for (QtreeNode<E> node : _children) {
content += node.toString() + ",";
}
result.append("{" + SHIFT + NEW_LINE +
content.substring(0, content.length()) +
SHIFT + NEW_LINE + "}");
} else if (_items != null) {
String content = "";
for (E item : _items) {
content += item.toString() + " ";
}
result.append("[" + content + "]");
}
return result.toString();
}
Provide separate toStringWithIndent(int depth) method for your tree Nodes, and call it inside overridden toString(). This method will call same one for each subnode, etc. recursively.
UPD Some example
class Node {
private String name;
private List<Node> children;
#Override
public String toString() {
String s = name;
for(Node n: children) s += children.toStringWithIndent(1);
return s;
}
private String toStringWithIndent(int depth) {
// same as toString() but with indent
String s = indentFor(depth) + name;
for(Node n: children) s += indentFor(depth) +
children.toStringWithDepth(depth + 1);
return s;
}
private static String indentFor(int depth) {
StringBuilder b = new StringBuilder(depth);
while(depth-- > 0) {
b.append(" ");
}
return b.toString();
}
}