How to print Binary Tree - java

I've been trying to switch over to Java from Node and one thing I'm wondering about is how to print an object such as a binary Tree in a similar format to how node would display it. For instance, my binary tree initiation code is as follows:
public class BinaryTree {
int data;
BinaryTree left, right;
public static void main(String[] args) {
BinaryTree tree = new BinaryTree(1);
tree= new BinaryTree(1);
tree.left = new BinaryTree(2);
tree.right= new BinaryTree(3);
tree.left.right = new BinaryTree(4);
System.out.println(tree); // output -> BinaryTree#4554617c
}
public BinaryTree(int data) {
super();
int val;
this.left = this.right = null;
}
}
In node, this binary tree would be displayed as the following:
TreeNode {
val: 1,
right: TreeNode { val: 3, right: null, left: null },
left:
TreeNode {
val: 2,
right: TreeNode { val: 4, right: null, left: null },
left: null } }
However in Java, when I do
System.out.println(tree);
the output -> BinaryTree#4554617c
What is the proper way to print my BinaryTree and what's a good way to do this? Is there a way to print the tree in a JSON format?

Printing tree will give you the memory address of the main tree node. If you want to print the content of the tree, you will need to implement a recursive print method and recurse over each node in the tree.
If the node is a final node (no right or left tree) print the content of that node. Otherwise move down the tree.
You can print on the way down the tree or on the way back depending on how you want the tree to look.
I hope I understood the question correctly.

I found this solution on stack overflow and modified it...
public static class TreeNode
{
int value;
TreeNode leftChildren;
TreeNode rightChildren;
public TreeNode(int value, TreeNode left, TreeNode right)
{
this.value = value;
this.leftChildren = left;
this.rightChildren = right;
}
public addLeftNode(TreeNode node)
{
this.leftChildren = node;
}
public addRightNode(TreeNode node)
{
this.rightChildren = node;
}
public void print(String prefix)
{
print(prefix, true);
}
private void print(String prefix, boolean isTail)
{
System.out.println(prefix + (isTail ? "└── " : "├── ") + this.toString());
if(null != leftChildren)
{
leftChildren.print(prefix + (isTail ? " " : "│ "), (null == rightChildren ? true : false));
}
if(null != rightChildren)
{
rightChildren.print(prefix + (isTail ?" " : "│ "), true);
}
}
#Override public String toString()
{
return "TreeNode { Value: " + this.value + "}";
}
}
The first node represents the left and the second node the right node in th binary tree.
EDIT: You can use this like this:
TreeNode root = new TreeNode(22, null, null);
root.addLeftNode(new TreeNode(15, null, null));
root.addRightNode(new TreeNode(35, new TreeNode(27, null, null), null));
root.print(); // This will print recursively all sub-nodes
Alternate you can write a wrapper class like this:
public class BinaryTree
{
private TreeNode root;
// implementation of getters and setters
public void print()
{
this.root.print();
}
}

Related

Insert string in a Binary tree

I am trying to create a binary tree that takes strings but it uses "-" and "+" to go left or right if the sign is + insert left and if it's - then insert right. Here is a visual representation of what I am trying to do.
insert method should take the word and just a single sign for now and based of that insert right or left
Here is my code but I am getting nullpointer error. Apparently, I am not inserting into the right order
public class BinaryTree {
private static Node root = null;
private static Node sign = null;
public static void main(String[] args) {
// TODO Auto-generated method stub
BinaryTree bt = new BinaryTree();
bt.insert("to", "-");
bt.insert("the", "+");
bt.preorder();
}
private class Node {
String data;
String sign;
Node left;
Node right;
public Node(String w) {
data = w;
left = right = null;
}
// public Node(String w, String s) {
// data = w;
// sign = s;
// left = right = null;
//
// }
} // -----------------end of Node
private void insert(String val, String sign) {
root = insert(root, val, sign);
}
Node insert(Node r, String data, String passSign) {
if (r == null) {
return new Node(data);
}
if(r.sign.equals(passSign)) {
r.right = insert(r.right, data, passSign);
}
else if (r.sign.equals(passSign)){
r.left = insert(r.left, data, passSign);
}
return r;
}
public void preorder() {
preorder(root);
}
public void preorder(Node p) {
if (p != null) {
System.out.println(p.data);
preorder(p.left);
preorder(p.right);
}
}
}
The main problems are:
The BinaryTree nor the Node instances should have a sign member. The sign only plays a role during the insertion process, but has no meaning any more once a node is inserted
r.sign.equals(passSign) is therefore also not the correct condition to check. According to your description you should just check whether the sign is a "-" and go right, or else go left ("+"). There is no state of the node that influences this decision. So do passSign.charAt(0) == '-' instead.
When making the recursive call you should not pass the same sign again: it has already been processed. Instead, pass any signs that follow after the consumed one. You can use substring for that purpose.
The image shows a root node that has no value. Yet you are right in creating a tree instance with no node at all. So your insert method should deal with the case where the root is null, but the sign argument is not the empty string. In that case a root node should be created, but it should not hold the target data, as for that we should still go deeper in the tree. This principle could apply to any node, not only the root. So foresee the creation of such "place-holder" nodes and give them some default value (like "(null)").
Not a problem, but I find it more useful to print in inorder order, and indent the deeper nodes. This way you get an idea how the tree is structured.
Here is the corrected code:
public class BinaryTree {
private static Node root = null;
// No sign member needed;
public static void main(String[] args) {
BinaryTree bt = new BinaryTree();
bt.insert("to", "-");
bt.insert("the", "+");
bt.insert("buy", "-+");
bt.insert("imperial", "+-");
bt.insert("afflication", "++");
bt.inorder();
}
private class Node {
String data;
// No sign member needed;
Node left;
Node right;
public Node(String w) {
data = w;
left = right = null;
}
}
private void insert(String val, String sign) {
root = insert(root, val, sign);
}
Node insert(Node r, String data, String passSign) {
// Check whether there is a sign
if (passSign.length() == 0) {
return new Node(data);
}
// If needed, create a placeholder node so to be able to descend further
if (r == null) {
r = new Node("(null)");
}
if (passSign.charAt(0) == '-') {
// Extract the rest of the signs
r.right = insert(r.right, data, passSign.substring(1, passSign.length()));
}
else {
r.left = insert(r.left, data, passSign.substring(1, passSign.length()));
}
return r;
}
public void inorder() {
inorder(root, "");
}
// This method gives a bit more visual output
public void inorder(Node p, String indent) {
if (p != null) {
inorder(p.left, indent + " ");
System.out.println(indent + p.data);
inorder(p.right, indent + " ");
}
}
}

Construction tree

I wrote a tree construction method. I don't see any errors when running it. However, when I'm testing the tree if it is symmetric or not and should return false (for input: [1,2,2,4,4, null, 6]) This means that I am putting root node as 1, second level: 2,2 third level: 4, 4, null, 6. It is returning true. I'm not sure what's wrong? I'm sure that my symmetric function is correct, I just don't know what's wrong with my tree construction? I tried debugging and I saw all the values in the array were implemented in the construction. Can someone let me know what's going on?
public class isSymmetric {
public static class TreeNode {
public int key;
public TreeNode left;
public TreeNode right;
public TreeNode(int key) {
this.key = key;
this.left = this.right = null;
}
}
public boolean symmetric(TreeNode root) {
...
}
//Tree test cases
public static TreeNode construction(Integer[] array) {
//use level order traversal to construct a tree
TreeNode root = new TreeNode(array[0]);
return constructionhelp(array, root, 0);
}
public static TreeNode constructionhelp(Integer[] array, TreeNode root, int i) {
if (root == null) {
return null;
}
if (i < array.length) {
root = new TreeNode(array[i]);
root.left = constructionhelp(array, root.left, 2*i+1);
root.right = constructionhelp(array, root.right, 2*i+2);
}
return root;
}
public static void main(String[] args) {
isSymmetric s = new isSymmetric();
Integer a[] = {1,2,2,4,4,null,6};
TreeNode roota = construction(a);
System.out.print(s.symmetric(roota));
}
}
//returning true;
What happens:
root = new TreeNode(array[i]); // you create new tree node instance
root.left = constructionhelp(array, root.left, 2*i+1); // root.left is null
root.right = constructionhelp(array, root.right, 2*i+2) // root.right is null
so after you call your constructionhelp again, you pass null as an argument of the node.
-> null is returned.
-> your tree is only the root.

Recursive function to calculate the height of a BST

The BST is as follows:
50 (Root 1)
/ \
40 80 (Root 2)
/ \
20 41
As you can see there are 2 root's that I am dealing with. I have tried the following code which does return the height of the tree from ROOT 1. I don't quite exactly know how to return the height from ROOT 2.
Any help on how to solve would be appreciated.
// Java program to find height of tree
// A binary tree node
class Node
{
int data;
Node left, right;
Node(int item)
{
data = item;
left = right = null;
}
}
class BinaryTree
{
Node root;
int maxDepth(Node node)
{
if (node == null)
return 0;
else
{
/* compute the depth of each subtree */
int lDepth = maxDepth(node.left);
int rDepth = maxDepth(node.right);
/* use the larger one */
if (lDepth > rDepth)
return (lDepth + 1);
else
return (rDepth + 1);
}
}
/* Driver program to test above functions */
public static void main(String[] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(5);
System.out.println("Height of tree is : " +
tree.maxDepth(tree.root));
}
Your function for finding max depth seems like to work correctly. So fixing this issue is pretty simple.
System.out.println("Height of tree is : " +
tree.maxDepth(tree.root));
The above line prints out the height of the tree starting at the root. But if you were to start at "root 2" as you call it you would need to modify this line to start at the correct node.
System.out.println("Height of tree is : " +
tree.maxDepth(tree.root.right));
Adding an item to a Tree class should be made through a insert method.
And we can make the Node class private, it is used only by BinaryTree class.
A better data structure for a tree should be like the following, which has public insert and height methods.
public class BinaryTree {
private class Node {
private int value;
private Node left;
private Node right;
private Node(int value) {
this.value = value;
}
}
private Node root;
public void insert(int item) {
var node = new Node(item);
if (root == null) {
root = node;
return;
}
var current = root;
while (true) {
if (item < current.value) {
if (current.left == null) {
current.left = node;
break;
}
current = current.left;
} else {
if (current.right == null) {
current.right = node;
break;
}
current = current.right;
}
}
}
public int height() {
return height(root);
}
private int height(Node root) {
if (root == null)
return -1;
if (isLeaf(root))
return 0;
return 1 + Math.max(height(root.left), height(root.right));
}
private boolean isLeaf(Node node) {
return node.left == null && node.right == null;
}
}
And to use it, just add some values, and print the height.
It is way easier to insert an item with this tree class.
BinaryTree tree = new BinaryTree();
tree.insert(50);
tree.insert(40);
tree.insert(80);
tree.insert(20);
tree.insert(41);
System.out.println(tree.height());

How to insert recursively into Binary Tree and also print the elements recursively?

This is the Java program I wrote to create a Binary Tree and insert elements into it. However, I could not write the program for inserting the elements recursively and thus had to manually specify the left and right children respectively.
Here is my code:
public class BinTree {
private Node root;
private class Node {
Node left;
Node right;
int data;
private Node(int data) {
this.data = data;
left = null;
right = null;
}
}
public BinTree() {
root = null;
}
public void preorder(Node temp) {
temp = root;
if(temp != null) {
System.out.print(temp.data + " ");
preorder(temp.left);
preorder(temp.right);
}
}
public void add() {
root = new Node(10);
root.left = new Node(20);
root.right = new Node(30);
root.left.left = new Node(40);
root.left.right = new Node(50);
root.right.left = new Node(60);
}
public static void main(String[] args) {
BinTree bt = new BinTree();
bt.add();
System.out.print(bt.root.data);
System.out.print(" " + bt.root.left.data);
System.out.print(" " + bt.root.right.data);
System.out.print(" " + bt.root.left.left.data);
System.out.print(" " + bt.root.left.right.data);
}
}
Also, the preorder traversal I wrote for the above program failed and I got some unending output. Had to kill the execution!
Hence if some one could provide me the correct implementation of inserting elements into binary tree recursively it would be of great help.
Also, if possible, could you please tell me where i made a mistake in my preorder traversal?
Thanks in advance!
To answer the question in part, the preorder function contains a bug as it does not actually traverse the tree but starts from the root over and over again. Change it to
public void preorder(Node temp)
{
if(temp != null)
{
System.out.print(temp.data + " ");
preorder(temp.left);
preorder(temp.right);
}
}
and call it with the root of the tree as an argument.

Converting an iterative Level Order Traversal (of a BST) to a recursive implementation

I have a working program that prints each level of a (complete) binary tree, using the "preferred" method of an iterative function (see code below), but I would like to see how one would implement the same program, but using a recursive method.
Although I agree that normally having someone write code for me is not conducive to good learning; I have more trouble learning how to do something without having seen a working implementation beforehand (because no precedent has been set).
What I have so far (iterative program):
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Collections;
public class BinaryTreeLevelWise<T extends Comparable<T>> {
/*
* This class represents the individual nodes of the binary tree
* Each node has a left, right pointer of type Node
* and Value to hold the value
*/
class Node<T> {
Node left;
Node right;
T value;
public Node(T value) {
this.value = value;
}
#Override
public String toString() {
return "Node value=" + value + "";
}
}
public static void main(String[] args) {
new BinaryTreeLevelWise().run();
}
/*
* This function inserts an element into the binary tree
*/
public <T> void insert(Node node, T value) {
if (((Comparable<T>) value).compareTo((T) node.value) < 0) {
if (node.left != null) {
insert(node.left, value);
} else {
System.out.println(" Inserted " + value + " to left of "
+ node.value);
node.left = new Node(value);
}
} else if (((Comparable<T>) value).compareTo((T) node.value) > 0) {
if (node.right != null) {
insert(node.right, value);
} else {
System.out.println(" Inserted " + value + " to right of "
+ node.value);
node.right = new Node(value);
}
}
}
public void run() {
Node root = new Node(5);
System.out.println("Building tree with root value " + root.value);
insert(root, 1);
insert(root, 8);
insert(root,-2);
insert(root, 6);
insert(root, 3);
insert(root, 9);
insert(root,-3);
insert(root,-1);
insert(root,-4);
System.out.println("*************\nPrinting the tree level by level");
printLevelWise(root);
}
/*
* This functions uses a list of nodes and prints them level by level,
* assuming a complete binary tree.
*/
public void printLevelWise(Node root) {
List<List<Node>> levels = traverseLevels(root);
int i = 0;
for (List<Node> level : levels) {
System.out.print("Level " + i + ": ");
for (Node node : level) {
System.out.print("node " + node.value + " -> ");
}
System.out.println();
i++;
}
}
/*
* This function traverses the tree and puts all the nodes into a list, level by level
*/
private List<List<Node>> traverseLevels(Node root) {
if (root == null) {
return Collections.emptyList();
}
List<List<Node>> levels = new LinkedList<>();
Queue<Node> nodes = new LinkedList<>();
nodes.add(root);
while (!nodes.isEmpty()) {
List<Node> level = new ArrayList<>(nodes.size());
levels.add(level);
for (Node node : new ArrayList<>(nodes)) {
level.add(node);
if (node.left != null) {
nodes.add(node.left);
}
if (node.right != null) {
nodes.add(node.right);
}
nodes.poll();
}
}
return levels;
}
}
This code outputs the following (which I believe to be the correct output):
Level 0: node 5 ->
Level 1: node 1 -> node 8 ->
Level 2: node -2 -> node 3 -> node 6 -> node 9 ->
Level 3: node -3 -> node -1 ->
Level 4: node -4 ->
Any ideas on how to make this program use a recursive method instead of an iterative method?
You can try below code for recursive way but if you compare complexity by then Queue way is better in compare to recursive method to traverse level order
public void printLevelOrder(Node<T> root)
{
int h = height(root);//Calculate height of the tree
int i;
for (i=1; i<=h; i++)
{
printGivenLevel(root, i);
System.out.println();
}
}
private void printGivenLevel(Node<T> root, int height) {
if (root == null)
return;
if (height == 1)
System.out.print(root.value);
else if (height > 1)
{
printGivenLevel(root.left, height-1);
printGivenLevel(root.right, height-1);
}
}

Categories

Resources