Binary Tree toString prints hashcode even after override - java

I made a program that inserts characters (letters) into a binary search tree. I am not encountering any errors but when I call the toString method, it only prints a part of the output with the hashcode of ht=10 [K=G R=BTNode#5b6f7412]. I might have overlooked something so it would be greatly appreciated if you could help me out. Thanks!
Expected Output (not the exact output but in this format)
ht=2 [K=A L=[K=B R=[K=C]] R=[K=D L=[K=E]]]
toString method
public String toString()
{
String s = "";
BTNode<T> n = root;
if (n == null)
{
return "";
}
if (n != null)
{
s = "ht=" + height + " [K=" + n.info;
if (n.left != null)
{
s = s + " L=" + n.left.toString() + "]";
}
if (n.right != null)
{
s = s + " R=" + n.right.toString() + "]";
}
}
return s;
}
Main Class
public static void main(String args[])
{
BST<Character> bst = new BST<>(); // instantiate BST object
// insert values to bst
bst.insert('A');
bst.insert('B');
bst.insert('C');
bst.insert('D');
bst.insert('E');
bst.insert('F');
// print bst1
System.out.println(bst.toString());
}

You have to write a method with the exact signature public String toString() in BTNode.
Writing public String toString(BTNode<N>) accomplishes nothing.

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

Using a recursive method to return an inorder string in java?

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.

Why does stack overflow occur when adding second elements to a double-linked list?

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 +
'}';
}

Binary Search Tree: Recursive toString

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);
}

Incrementing shift for 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();
}
}

Categories

Resources