Binary Search Tree: Recursive toString - java

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

Related

How to print binary search tree in nice diagram?

I have to implement binary search tree with method that prints nice diagram with connections like this:
For now I managed to print this:
However I'm struggling to make it better :/
Do you have any hints how to fix that?
It's my code of instance implementing it:
public interface PrintableTree {
class Node {
int data;
Node left, right;
Node(int data) {
this.data = data;
this.left = null;
this.right = null;
}
}
class Trunk {
Trunk prev;
String str;
Trunk(Trunk prev, String str) {
this.prev = prev;
this.str = str;
}
}
Node insert_Recursive(Node root, int key);
void add(int i);
String prettyPrint();
static PrintableTree getInstance() {
return new PrintableTree() {
String stringOfTree = "";
static final int COUNT = 2;
Node root;
#Override
public void add(int i) {
root = insert_Recursive(root, i);
}
#Override
public Node insert_Recursive(Node root, int key) {
if (root == null) {
root = new Node(key);
return root;
}
if (key < root.data)
root.left = insert_Recursive(root.left, key);
else if (key > root.data)
root.right = insert_Recursive(root.right, key);
return root;
}
#Override
public String prettyPrint() {
printTree(root, null, false);
return "";
}
public void showTrunks(Trunk p) {
if (p == null) {
return;
}
showTrunks(p.prev);
System.out.print(p.str);
}
public void printTree(Node root, Trunk prev, boolean isLeft) {
if (root == null) {
return;
}
String prev_str = " ";
Trunk trunk = new Trunk(prev, prev_str);
printTree(root.left, trunk, true);
if (prev == null) {
trunk.str = "";
} else if (isLeft) {
trunk.str = "┌";
prev_str = " │";
} else {
trunk.str = "└";
prev.str = prev_str;
}
showTrunks(trunk);
System.out.println(" " + root.data);
if (prev != null) {
prev.str = prev_str;
}
trunk.str = " │";
printTree(root.right, trunk, false);
}
};
}
}
You could use these functions. They return a string, so it is up to the caller to print it.
I also find it nicer when the right subtree is printed upwards, and the left subtree downwards. That way, the tree is just rotated 90° from how it is usually depicted -- with the root at the top.
Here is the relevant code:
public String pretty() {
return pretty(root, "", 1);
}
private String pretty(Node root, String prefix, int dir) {
if (root == null) {
return "";
}
String space = " ".repeat(("" + root.data).length());
return pretty(root.right, prefix + "│ ".charAt(dir) + space, 2)
+ prefix + "└ ┌".charAt(dir) + root.data
+ " ┘┐┤".charAt((root.left != null ? 2 : 0)
+ (root.right != null ? 1 : 0)) + "\n"
+ pretty(root.left, prefix + " │".charAt(dir) + space, 0);
}

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

insert method of the Trie data structure

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.

How do I print my linked list?

If you look at my toString() method below, you can see that I have not finished it. I don't know how? Can anyone explain how I might proceed? Confused :-| I'm new to linked lists and so I automatically went for the Arrays.toString() approach before I realized that there is, of course, no arrays anywhere.
import java.util.Arrays;
public class LinkedIntegerStack {
private Node top = null;
private int size = 0;
public int size(){
return size;
}
public boolean isEmpty() {
if(top == null){
return true;
}
else{
return false;
}
}
public void push(int value) {
Node n = new Node(value);
n.next = top;
top = n;
size++;
}
public int top(){ //just returns a value..doesn't change structure
return top.element;
}
public int pop(){
if (isEmpty()){
throw new StackEmptyException();
}
int toReturn = top.element;
top = top.next;
size--;
return toReturn;
}
public String toString() {
return "[ Top = " + size +"]" + "[Stack = " );
}
private class Node {
int element;
Node next;
public Node(int value){
element = value;
}
}
public static void main(String[] args) throws StackEmptyException{
LinkedIntegerStack stack = new LinkedIntegerStack();
stack.push(17);
System.out.println(stack);
stack.push(11);
System.out.println(stack);
try{
stack.pop();
System.out.println(stack);
}
catch(StackEmptyException ex){
System.out.print("Stack is Empty: Error");
}
System.out.println("Stack: " + stack);
}
}
The solution is pretty easy.
It should be enough to iterate through the stack.
public String toString() {
String result = "[ Top = " + size +"]" + "[Stack = [";
if (top == null) {
return result + "]]";
Node temp = top;
while (temp != null) {
result += temp + ', '
temp = temp.next;
}
return result += temp.element + "]]";
}
Of course you should add at least getter methods to Node class, i.e. getElement() and getNext();
PS: the code isn't tested, but it should be fine.
System.out.println(Arrays.toString(stack.toArray()));
From https://stackoverflow.com/a/395403/2736496
JavaDoc: Arrays.toString(o[]), Collection.toArray(cll)

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