error in creating a balanced binary tree using Java - java

I wrote this code to create a binary tree but looks like this code is creating an unbalanced binary tree. The nodes are getting only on the right subtree of root. I get Null pointer exception if I try to access child nodes of left subtree. I want to create a balanced binary tree with nodes getting inserted from left to right. What mistake am I doing here and how to rectify it?
public class binTree {
public static class TreeNode{
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val){
this.val = val;
this.left = null;
this.right = null;
}
}
public TreeNode root;
public binTree(){
this.root = null;
}
public void insert(int data){
root = insert(root,data);
}
public TreeNode insert(TreeNode node,int data){
if(node == null){
node = new TreeNode(data);
//root = node;
}
else{
if(node.left == null){
node.left = insert(node.left,data);
}
else{
node.right = insert(node.right,data);
}
}
return node;
}
public static void main(String args[]){
binTree obj = new binTree();
obj.insert(5);
obj.insert(11);
obj.insert(13);
obj.insert(1);
obj.insert(7);
obj.insert(21);
obj.insert(35);
System.out.println(obj.root.right.left.val);
System.out.println(obj.root.left.right.val); // this throws null pointer exception
}
}

You'll need to store the quantity of elements for every sub-tree at each tree-node like this:
public class BinTree {
private TreeNode root;
public static class TreeNode {
public int val;
public int elements = 0;
public TreeNode left;
public TreeNode right;
public TreeNode(int val) {
this.val = val;
this.left = null;
this.right = null;
}
}
public BinTree() {
this.root = null;
}
public void insert(int data) {
root = insert(root, data);
}
private static int height(TreeNode node) {
int result = 0;
if (node != null) {
result++;
int total = node.elements;
int heightElements = 2;
while (total > heightElements) {
total -= heightElements;
heightElements *= 2;
result++;
}
}
return result;
}
public TreeNode insert(TreeNode node, int data) {
if (node == null) {
node = new TreeNode(data);
} else if (height(node.left) == height(node.right)) {
node.left = insert(node.left, data);
} else {
node.right = insert(node.right, data);
}
node.elements++;
return node;
}
public static void main(String args[]) {
BinTree obj = new BinTree();
obj.insert(5);
obj.insert(11);
obj.insert(13);
obj.insert(1);
obj.insert(7);
obj.insert(21);
obj.insert(35);
System.out.println(obj.root.val);
System.out.println(obj.root.left.val);
System.out.println(obj.root.right.val);
System.out.println(obj.root.left.left.val);
System.out.println(obj.root.left.right.val);
System.out.println(obj.root.right.left.val);
System.out.println(obj.root.right.right.val);
}
}

Related

Binary Tree use String

I have to make a source code about binary tree from anything type. That means the input is string, so in my opinion, I must convert the string into byte[ ] then get the ASCII code from that. But I don't know how to make binary tree from byte or convert that byte[ ] into integer. I'm stuck right now.
class Node{
int data;
Node left, right;
public Node(int data){
this.data = data;
Node left = right = null;
}
}
class BinaryTree{
public Node root;
public void newNode(int data){
if(root == null){
root = newNode(root, new Node(data));
}
}
private Node newNode(Node root, Node newData){
if(root == null){
root = newData;
return root;
}
if(newData.data < root.data){
root.left = newNode (root.left, newData);
}else{
root.right = newNode (root.right, newData);
}
return root;
}
public void inOrder(Node node){
if(node !=null){
inOrder(node.left);
System.out.println(node.data + " ");
inOrder(node.right);
}else{
return;
}
}
public void preOrder(Node node){
if(node !=null){
System.out.println(node.data +" ");
preOrder(node.left);
preOrder(node.right);
}else{
return;
}
}
public void postOrder(Node node){
if(node !=null){
preOrder(node.left);
preOrder(node.right);
System.out.println(node.data +" ");
}else{
return;
}
}
}
public class ALPROMOD5{
public static void main(String[] args) throws UnsupportedEncodingException {
Scanner scan = new Scanner(System.in);
String inp;
System.out.println("String to ASCII");
System.out.println("Binary Tree from Converted String to Char");
System.out.print("\nMasukan Inputan : ");
inp = scan.nextLine();
byte[] bt = inp.getBytes("US-ASCII");
System.out.print("ASCII Value of("+inp+") is : ");
System.out.println(Arrays.toString(bt));
}
}
Look at generics. No need to convert your data at all. Here's a place to start:
NOTE: For comparisons, use the compareTo() method from the comparable interface.
public class Node<T extends Comparable<T>> {
private T payload;
private Node<T> leftNode;
private Node<T> rightNode;
public Node(T payload) {
this.payload = payload;
}
public T getPayload() {
return payload;
}
public Node<T> getLeftNode() {
return leftNode;
}
public Node<T> getrightNode() {
return rightNode;
}
public void setLeftNode(Node<T> left) {
leftNode = left;
}
public void setRightNode(Node<T> right) {
rightNode = right;
}
}
public class BinaryTree<T extends Comparable<T>> {
private Node<T> root;
public BinaryTree(T rootPayload) {
root = new Node<T>(rootPayload);
}
public Node<T> addNode(T data) {
return add(root, data);
}
private Node<T> add(Node<T> root, T data) {
//Add your code returning the node representing the data.
return null;
}
}

Transferring a String array to Binary Tree

I'm trying to write a method that can transfer an array into a Binary tree. I know the code is not right, I run it and hope it would show something that I can continue to fix it. But it just kept loading without any error or result. May anyone give me some advice, please!
Here is the BST class:
public class BSTNode {
private String data;
private BSTNode left;
private BSTNode right;
public BSTNode(String data) {
this.data = data;
this.right = null;
this.left = null;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public BSTNode getLeft() {
return left;
}
public void setLeft(BSTNode left) {
this.left = left;
}
public BSTNode getRight() {
return right;
}
public void setRight(BSTNode right) {
this.right = right;
}
}
And my method:
public BSTNode fromArray(String[] array, int start, int end) {
int i = start;
BSTNode root = new BSTNode(array[i]);
BSTNode current = root;
BSTNode parent = null;
while (i <= end) {
if (array[i].compareTo(current.getData()) < 0) {
parent = current;
current.setLeft(current); //Should I put current.setLeft(root) here?
} else {
parent = current;
current.setRight(current);
}
// Create the new node and attach it to the parent node
if (array[i].compareTo(parent.getData()) < 0) {
parent.setLeft(new BSTNode(array[i]));
} else {
parent.setRight(new BSTNode(array[i]));
}
i++;
}
return current;
}
Thank you for your time!
After you've initialized the root, you've already inserted the first element, so you can increment i right away.
You set the left and right pointers without keeping track of the prior value.
You never change the value of current within the loop, and, as you immediately assign it to parent, you don't change parent either.
You should return the root instead of the current node.
How about something like this:
while (++i <= end) {
current = root;
while (current != null) {
parent = current;
if (array[i].compareTo(current.getData()) < 0) {
current = current.getLeft();
} else {
current = current.getRight();
}
}
// Create the new node and attach it to the parent node
if (array[i].compareTo(parent.getData()) < 0) {
parent.setLeft(new BSTNode(array[i]));
} else {
parent.setRight(new BSTNode(array[i]));
}
}
return root;
UPDATE:
You can avoid a redundant comparison by keeping its result in a variable:
while (++i <= end) {
boolean left;
current = root;
do {
parent = current;
left = array[i].compareTo(current.getData()) < 0;
if (left) {
current = current.getLeft();
} else {
current = current.getRight();
}
} while (current != null);
// Create the new node and attach it to the parent node
if (left) {
parent.setLeft(new BSTNode(array[i]));
} else {
parent.setRight(new BSTNode(array[i]));
}
}
return root;
public class Main {
public static final class Node {
public static final String NULL = "_";
public static final String SPLIT = ",";
private final String val;
private Node left;
private Node right;
public Node(String val) {
this.val = val;
}
}
public static void main(String... args) {
Node root = createBinaryTree();
String str = serialize(root); // 0,1,3,7,_,9,_,_,_,4,_,_,2,5,_,8,_,_,6,_,_
Node newRoot = deserialize(str);
}
private static String serialize(Node root) {
StringBuilder buf = new StringBuilder();
serialize(root, buf);
return buf.toString();
}
private static void serialize(Node node, StringBuilder buf) {
if (buf.length() > 0)
buf.append(Node.SPLIT);
if (node == null)
buf.append(Node.NULL);
else {
buf.append(node.val);
serialize(node.left, buf);
serialize(node.right, buf);
}
}
private static Node deserialize(String str) {
String[] values = str.split(Node.SPLIT);
return deserialize(values, new AtomicInteger());
}
private static Node deserialize(String[] values, AtomicInteger i) {
if (i.get() >= values.length)
return null;
String value = values[i.getAndIncrement()];
if (Node.NULL.equalsIgnoreCase(value))
return null;
Node node = new Node(value);
node.left = deserialize(values, i);
node.right = deserialize(values, i);
return node;
}
/*
* 0
* / \
* 1 2
* / \ / \
* 3 4 5 6
* / \
* 7 8
* \
* 9
*/
private static Node createBinaryTree() {
Node[] nodes = { new Node("0"), new Node("1"), new Node("2"), new Node("3"),
new Node("4"), new Node("5"), new Node("6"), new Node("7"),
new Node("8"), new Node("9") };
nodes[0].left = nodes[1];
nodes[0].right = nodes[2];
nodes[1].left = nodes[3];
nodes[1].right = nodes[4];
nodes[2].left = nodes[5];
nodes[2].right = nodes[6];
nodes[3].left = nodes[7];
nodes[5].right = nodes[8];
nodes[7].right = nodes[9];
return nodes[0];
}
}

How to populate the BST and also print it in Inorder way

I am trying this code to populate the BST and then print it in the InOrder traversal format. But the root node is not getting populated compiling wihtout any error and Output is : "root is empty", so how to correct this code so that my BST gets populated in the Node root.
I tried to make Node root as static I thought it might be the case that root node might not be accessible from each method but it is not working, tried to change the name of the Node but it is also not working.
import java.util.*;
import java.io.*;
import java.lang.*;
class Node{
int data; Node left; Node right;
public Node(int data) {
this.data = data;
left = null;
right = null;
}
}
public class insert_tree {
static Node root;
insert_tree() //constructor
{
root = null;
}
public void addNode(int value) { // public method is called by the object and this public method calls the private method in which the root is also passed.
root = add(root, value);
}
private Node add(Node node, int value) {
if(node == null) {
return node;
}
if(value < node.data) {
node.left = add(node.left, value);
}
else if(value > node.data) {
node.right = add(node.right, value);
}
else {
return node;
}
return node;
}
private void inOrder(Node node) {
// node = root;
if(node != null) {
inOrder(node.left);
System.out.print(node.data + " ");
inOrder(node.right);
}
else {
System.out.print("root is empty");
}
//return null;
}
public void inorder() {
inOrder(root);
}
private void printRoot(Node root) {
System.out.println(root.data);
}
public void print() {
printRoot(root);
}
public static void main(String args[]) {
insert_tree obj = new insert_tree();
obj.addNode(20);
obj.addNode(14);
obj.addNode(25);
obj.addNode(10);
obj.addNode(16);
obj.addNode(25);
obj.addNode(21);
obj.addNode(30);
//printing the tree
obj.inorder();
}
}
The output should be the inorder traversal of the tree.
public void addNode(int value) { // public method is called by the object and this public method calls the private method in which the root is also passed.
root = add(root, value);
}
private Node add(Node node, int value) {
if(node == null) {
node = new Node(value);
}
else if(value == node.data) {
node.data = value;
}
else if(value < node.data) {
node.left = add(node.left, value);
}
else {
node.right = add(node.right, value);
}
return node;
}

Binary Tree in Java without using add method

I've been trying to switch over to Java from Node and one thing I'm wondering about is how to construct a Binary Tree without putting a sorting algorithm in. In Node, I could simply type the following:
function TreeNode(val) {
this.val = val;
this.left = this.right = null;
}
let tree = new TreeNode(4);
tree.left = new TreeNode(2);
tree.left.left = new TreeNode(1);
What is the Java equivalent to this? This is my current thought process
public class BinaryTree {
private static TreeNode root;
public static void main(String[] args) {
BinaryTree bt = new BinaryTree();
bt.TreeNode = ??
}
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
}
#EJP: There is no need for two classes. Every tree node is a tree.
OP: Can you show me this with one class.
Based on the code https://stackoverflow.com/a/50072165/139985 ....
public class BinaryTree {
int data;
BinaryTree left, right;
public BinaryTree(int data) {
super();
this.data = data;
this.left = this.right = null; // redundant ...
}
public int height() {
height(this);
}
private int height(BinaryTree node) {
if (node == null) {
return 0;
}
return Math.max(height(node.left), height(node.right)) + 1;
}
public static void main(String[] args) {
BinaryTree tree = new BinaryTree(1);
tree.left = new BinaryTree(2);
tree.right = new BinaryTree(3);
tree.left.right = new BinaryTree(4);
System.out.println("The height of given binary tree is : " + tree.height());
}
}
You can structure your code something like this
class Node {
int data;
Node left, right;
public Node(int data) {
super();
this.data = data;
this.left = this.right = null;
}
}
public class BinaryTree {
Node root;
public int height(Node node) {
if (node == null)
return 0;
return Math.max(height(node.left), height(node.right)) + 1;
}
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.right = new Node(4);
System.out.println("The height of given binary tree is : " + tree.height(tree.root));
}
}

Why is the recursive insertion method of the BST not working

I wrote the following code to implement the recursive insert method for the BST. But when I print the tree in walk over order it prints the original tree before insertion. It seems as if the element was not inserted. Please help me out. Thanks in advance. Also please suggest the change in code. By the way, the intial tree in walk over order is 2 5 5 6 7 8.
package DataStructures;
class TreeNode {
private TreeNode parent;
private TreeNode childLeft;
private TreeNode childRight;
private int key;
public TreeNode(){
}
public TreeNode(int key) {
this(key, null);
}
public TreeNode(int key, TreeNode parent) {
this(key, parent, null, null);
}
public TreeNode(int key, TreeNode parent, TreeNode childLeft, TreeNode childRight) {
this.key = key;
this.parent = parent;
this.childLeft = childLeft;
this.childRight = childRight;
}
public int getKey() {
return key;
}
public void setKey(int key) {
this.key = key;
}
public TreeNode getParent() {
return parent;
}
public void setParent(TreeNode parent) {
this.parent = parent;
}
public TreeNode getChildLeft() {
return childLeft;
}
public void setChildLeft(TreeNode childLeft) {
this.childLeft = childLeft;
}
public TreeNode getChildRight() {
return childRight;
}
public void setChildRight(TreeNode childRight) {
this.childRight = childRight;
}
}
public class BinarySearchTreeBasicTest {
private static class BinarySearchTree {
private TreeNode root;
private TreeNode maxNode = new TreeNode(0);
public BinarySearchTree(TreeNode root) {
this.root = root;
}
public void printTheTreeInOrderWalk(TreeNode x) {
if (x != null) {
printTheTreeInOrderWalk(x.getChildLeft());
System.out.print(x.getKey() + " ");
printTheTreeInOrderWalk(x.getChildRight());
}
}
public void insertNode(TreeNode node, int key){
if (node == null){
node = new TreeNode(key);
}
else{
if (node.getKey() > key){
insertNode(node.getChildLeft(), key);
} else if (node.getKey() < key){
System.out.println("k");
insertNode(node.getChildRight(), key);
} else{
// dont do anything
}
}
}
}
public static void main(String[] args) {
TreeNode rootNode = new TreeNode(6);
BinarySearchTree tree = new BinarySearchTree(rootNode);
TreeNode node1 = new TreeNode(5);
TreeNode node2 = new TreeNode(7);
rootNode.setChildLeft(node1);
rootNode.setChildRight(node2);
node1.setParent(rootNode);
node2.setParent(rootNode);
TreeNode node3 = new TreeNode(2);
TreeNode node4 = new TreeNode(5);
node1.setChildLeft(node3);
node1.setChildRight(node4);
node3.setParent(node1);
node4.setParent(node1);
TreeNode node5 = new TreeNode(8);
node5.setParent(node2);
node2.setChildRight(node5);
tree.insertNode(rootNode, 3);
tree.printTheTreeInOrderWalk(rootNode);
}
}
In your insertNode() method, you are just creating a new node; you are never adding the newly created node to its parent. You should check whether you are going to insert here or not or you should return the newly returned node and set it accordingly.
If you don't want too much deviation from your current program, you can make the following changes.
public void insertNode(TreeNode node, int key) {
if (node.getKey() > key) {
if (node.left == null) { //check if you want to insert the node here
TreeNode newNode = new TreeNode(key);
node.left = newNode;
} else {
insertNode(node.getChildLeft(), key);
}
} else if (node.getKey() < key) {
if(node.right == null){ //check if you want to insert the node here
TreeNode newNode = new TreeNode(key);
node.right = newNode;
} else {
insertNode(node.getChildRight(), key);
}
} else {
// don't do anything
}
}
In Java, parameters are passed by value. In insertNode, if you don't do anything else with the node, the line node = new TreeNode(key); will not do anything useful.
The typical implementation of an insertion in a tree works by returning the TreeNode that will replace the previous one:
private TreeNode insertNode(TreeNode node, int key){
if (node == null){
node = new TreeNode(key);
}
else{
if (node.getKey() > key){
node.setChildLeft(insertNode(node.getChildLeft(), key));
} else if (node.getKey() < key){
node.setChildRight(insertNode(node.getChildRight(), key));
} else{
// dont do anything
}
}
return node;
}
Going a bit further, the previous method should actually be private. The public method should look like this:
public void insertNode(int key){
root = insertNode(root, key);
}

Categories

Resources