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();
}
}
Related
I want to make an in order transversal of a binary tree. I made this method:
public String inorder()
{
String inorder = "";
return recrInorder(this.root, inorder);
}
then i have a helper method:
private String recrInorder(Node curr,String string)
{
if(curr == null)
{
return "";
}
//Go through left
recrInorder(curr.getLeft(), string);
string = string + curr.getData() + ", ";
//Go through right
recrInorder(curr.getRight(), string);
return string;
}
This will only print the root, i want the whole list printed.
In Java parameters are passed by value for object reference so assigning new value to your input parameter named string will not change its value outside of that function.
You need to change your code like this
private String recrInorder(Node curr,String string)
{
if(curr == null)
{
return string; // preserve previously calculated value
}
//Go through left
string = recrInorder(curr.getLeft(), string);
string = string + curr.getData() + ", ";
//Go through right
string = recrInorder(curr.getRight(), string);
return string;
}
public String inorder() {
return recrInorder(this.root);
}
private String recrInorder(Node curr) {
if (curr == null) return "";
return recrInorder(curr.getLeft()) + curr.getData() + ", " + rectInorder(curr.getRight());
}
Given a parent, left child, and right child relationship, the traversal of the tree is dependent on when you visit the parent and access the String value.
Given the root of the tree call it as follows:
String s = traverse(root, "");
System.out.println(s);
public static String traverse(Node n, String s) {
if (n == null) {
return s;
}
// s += n.value; // uncomment this assignment for preorder traversal
s = traverse(n.left,s);
// s += n.value; // uncomment this assignment for inorder traversal
s = traverse(n.right,s);
// s += n.value; // uncomment this assignment for postorder traversal
return s;
}
So in your method, you could pass a flag or enum and caveat the assignment based on that value, thus adapting your method to any traversal.
I created a double-linked list and it can run without any error.But it will occur java.lang.StackOverflowError at adding second element when i use debug to examine this program.If i don't override toString(),the program will be normal.But i want to know why don't override toString()?
package com.study.testcollection.com.study.testlinkedlist;
public class Node {
private Node per;
private Object obj;
private Node next;
public Node getPer() {
return per;
}
public Object getObj() {
return obj;
}
public Node getNext() {
return next;
}
public void setPer(Node per) {
this.per = per;
}
public void setObj(Object obj) {
this.obj = obj;
}
public void setNext(Node next) {
this.next = next;
}
#Override
//if don't write this function,the program will be normal.Why?
public String toString() {
return "Node{" +
"per=" + per +
", obj=" + obj +
", next=" + next +
'}';
}
}
package com.study.testcollection.com.study.testlinkedlist;
public class Mylinkedlist {
Node first = null;
Node last = null;
public void add(Object e){
if (first == null){
Node n = new Node();
n.setObj(e);
n.setPer(null);
n.setNext(null);
first = n;
last = n;
}
else{
Node n = new Node();
n.setObj(e);
last.setNext(n);
n.setPer(last);
n.setNext(null);
last = n;
}
}
public static void main(String[] args) {
Mylinkedlist a = new Mylinkedlist();
a.add("hello");
a.add("Bob");//occur error when it is executed
}
}
Your "next" field is pointing to a Node and thus Node.toString() is called infinitely resulting in stackoverflow.
If you need to use toString() method, you can modify it as follows :
public String toString() {
String n = next != null ? next.obj.toString():"null";
String p = per != null ? per.obj.toString():"null";
return "Node{" +
"per=" + p +
", obj=" + obj +
", next=" + n +
'}';
}
This is how it looks. When you do :
System.out.println(a.first.toString());
And when toString is defined as:
public String toString() {
return "Node{" +
"per=" + per +
", obj=" + obj +
", next=" + next +
'}';
}
You attempt in printing the next which is n
n attempts in printing the previous per
Previous per again attempts in printing next
next makes a call to previous per and so on...
Resulting in stackoverflow as the call never ends. You are again and again iterating in the forward arrow and previous arrow as shown in image above.
To fix it, you can remove toString from Node and replace with:
public String forward() {
return "Node{" +
", obj=" + obj +
", next=" + next +
'}';
}
public String backward() {
return "Node{" +
", obj=" + obj +
", prev=" + per +
'}';
}
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 + ")";
}
I have a toString with a helper method to print out the results of a circular linked list class I created. This is it:
/**
* Returns a String version of this.
*
* #return A String description of this.
*/
public String toString(){
String string = "";
DoubleNode<E> current = this.head;
string += stringHelper(this.head);
return string;
}
//Helps the full to string method
private String stringHelper(DoubleNode<E> node){
String string = "";
if(node == null){
return string;
}
System.out.println("Node value: " + node.getValue());
node = node.getNextLink();
if(node == this.head){
string += node.getValue();
return string;
}
else{
string += node.getValue();
return (stringHelper(node.getNextLink()) + ", " + string);
}
}
However, it appears to not be working. I have a test case where it should print out 40, 10, 2, but it prints out only 40, 10. Can anyone help me with this?
I believe you should replace the recursive call stringHelper(node.getNextLink()) with stringHelper(node), as you call node.getNextLink() twice in stringHelper() method which is not right.
I figured it out. Sorry for posting this, as I should have done this on my own. I ended up doing:
/**
* Returns a String version of this.
*
* #return A String description of this.
*/
public String toString(){
String string = "";
DoubleNode<E> current = this.head;
string += stringHelper(this.head);
return string;
}
//Helps the full to string method
private String stringHelper(DoubleNode<E> node){
String string = "";
if(node == null){
return string;
}
string+= node.getValue();
string+= ", ";
node = node.getNextLink();
if(node == this.head){
return string;
}
else{
string += node.getValue();
return (string + ", " + stringHelper(node.getNextLink()));
}
}
It only prints out one item.
It is suppose to print the contents of the tree in ascending order
public String toString()
{
return toString (_root);
}
private String toString(BSTnode root)
{
if (root == null)
return "";
toString(root._left);
toString(root._right);
return root._data.toString();
}
How do you want to show them?
You need to append the Strings, for example.
private String toString(BSTnode root)
{
StringBuilder builder = new StringBuilder();
if (root == null)
return "";
builder.append(toString(root._left));
builder.append(toString(root._right));
return builder.append(root._data.toString()).toString();
}
or just use a concatenation on strings.
private String toString(BSTnode root)
{
String result = "";
if (root == null)
return "";
result += toString(root._left);
result += toString(root._right);
result += root._data.toString()
return result;
}
//Helper
public String toString(){
return "<" +toString(root) + ">";
}
//recursively printing out the nodes
public static String toString(Node r){
if(r==null)
return "";
else
return toString(r.left) + " " +r.value + " " +toString(r.right);
}
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
// Helper
public String toString() {
return "<" + toString(this) + ">";
}
// recursively printing out the nodes
public static String toString(TreeNode r) {
if (r == null)
return "";
else
return r.val + " " + toString(r.left) + " " + toString(r.right);
}
}
public String toString(){
return toString (_root);
}
public String toStringAscending(BSTnode node)
{
if (node == null) return "";
return toStringAscending(node.left) + node._data.toString() + toStringAscending(node.right);
}