I know there are a lot of similar questions on here. I've looked at them, but everyone's implementation is different and it's just confusing me. I am trying to make a binary tree. Every time I insert an element, it becomes the root which is not what I want. If I try to access the data at the root from the main method or pass the root into another method, I get a null pointer exception. Can anyone tell me why my root is always null and why my insert method is not assigning a value to the root? Any tips on better design for data structures in Java would also be much appreciated.
package interviewQuestions;
public class BinaryTree {
private Node root = null;
private class Node {
int data;
Node left;
Node right;
public Node(int dataval){
data = dataval;
left = null;
right = null;
}
}
// A binary search tree must have no duplicate nodes
// Insert nodes into the tree. Return 1 on success.
public int insert(Node root, int data){
Node temp = root;
if(root == null){
Node node = new Node(data);
root = node;
System.out.println("new root is "+root.data);
return 1;
}
else if(temp.data < data && temp.right != null){
if(data < temp.right.data){
Node node = new Node(data);
node.right = temp.right;
temp.right = node;
return 1;
}
else{
temp = temp.right;
insert(temp, data);
}
}
else if(temp.data < data && temp.right == null){
Node node = new Node(data);
temp.right = node;
return 1;
}
else if(temp.data > data && temp.left != null){
if(data > temp.left.data){
Node node = new Node(data);
node.left = temp.left;
temp.left = node;
return 1;
}
else{
temp = temp.left;
insert(temp, data);
}
}
else if(temp.data > data && temp.left == null){
Node node = new Node(data);
temp.left = node;
return 1;
}
return -1;
}
public void preOrder(Node root){
if(root.left != null){
System.out.println(root.data);
root = root.left;
preOrder(root);
}
else if(root.left == null && root.right != null){
System.out.println(root.data);
root = root.right;
preOrder(root);
}
else if(root.left == null && root.right == null){
return;
}
}
// Remove
// Find
// Balance
public static void main (String[] args){
BinaryTree tree = new BinaryTree();
tree.insert(tree.root, 5);
tree.insert(tree.root, 2);
tree.insert(tree.root, 8);
tree.insert(tree.root, 1);
tree.insert(tree.root, 3);
tree.insert(tree.root, 9);
tree.insert(tree.root, 20);
tree.insert(tree.root, 10);
tree.insert(tree.root, 15);
System.out.println(tree.root);
tree.preOrder(tree.root);
System.out.println("Ya. everysing ees güten tag. YA.");
}
}
You are passing in a root variable when root is a private variable in your class. Fix your insert statement to only receive data and change private variable root to equal node.
Your method causes it to set the parameter root to node. This results in no change to the classes root.
You don't need to change the visibility of the root. When you enter the insert statement you have 2 different root variables in your code; the root you declared in your class and the root you passed as a parameter. You only want the one in the class
Related
I am having trouble figuring out how to set a variable "minData" to the minimum value inserted into a binary search tree. If I am thinking of this correctly, the most minimum value in the tree will always be in the left subtree so my code for setting this minimum value should go under the "else if (root.data < data)" statement. I also don't know how to access the minData variable inside my insert method. My code so far is:
private class Node {
int key;
int data;
int minData;
private Node left;
private Node right;
private Node root;
Node(int data) {
this.data = data;
left = null;
right = null;
root = null;
}
}
public TheBST(Node root) {
root = null;
}
public void insert(Node root, int data) {
Node newNode = new Node(data);
if(root == null) {
Node node = new Node(data);
root = node;
}
else if(root.data > data) {
if(root.left == null) {
Node node = new Node(data);
root.left = node;
}
insert(root.left, data);
}
else if(root.data < data) {
if(root.right == null) {
Node node = new Node(data);
root.right = node;
return;
}
insert(root.right, data);
}
}
Your forming of BST is not accurately done. You need to return from the method (or stack fragment of memory in case recursive procedure) when you would actually find the place to insert.
Add the return statement for the left-subtree:
else if(root.data > data) {
if(root.left == null) {
Node node = new Node(data);
root.left = node;
return;
}
insert(root.left, data);
}
Which is you are doing in case of the right-subtree.
P.S: once you are done with tree insertion, you can return the left-most-node from left-subtree, it would have the minimum value.
I wrote the following code for finding the height of the binary tree, this is wrong, its failing the test cases, but why it is wrong, how to prove logically that this is wrong?
// WRONG CODE
public static int height(Node root) {
if(root != null){
if(root.left != null && root.right != null){
return Math.max(height(root.left), height(root.right)) + 1;
}else if(root.left != null){
return height(root.left);
}else{
return height(root.right);
}
}
return 0;
}
Whereas this following code is right!!
//RIGHT WORKING CODE
public static int height(Node root) {
if(root != null){
if(root.left != null || root.right != null){
return Math.max(height(root.left), height(root.right)) + 1;
}
}
return 0;
}
What is the big difference between the two codes that makes one of them right and other the wrong one?
For clarity the class code for the Node is added here.
class Node {
Node left;
Node right;
int data;
Node(int data) {
this.data = data;
left = null;
right = null;
}
}
And this is the logic to insert a node into the binary tree.
public static Node insert(Node root, int data) {
if(root == null) {
return new Node(data);
} else {
Node cur;
if(data <= root.data) {
cur = insert(root.left, data);
root.left = cur;
} else {
cur = insert(root.right, data);
root.right = cur;
}
return root;
}
In the second and third cases (just a left node, or just a right node) you're not adding one to account for the node you're currently on.
By the way your code also has a potential bug, in that it's possible for both left and right to be null. Your height function can handle null so really none of this checking is necessary, except for the check on the first line of the height function itself. But if it's important to check for null in the second case, then you should check for null in the third case too.
I have written a Code for AVL Tree Insertion but when I try to print the value of Root Node it always returns Null. I am unable to understand the reason.Anyone who can solve this problem? I have tried many times but I could not resolve the problem. I am confused. I hope that someone from here will help in the case of resolving the problem I have as I am sure there are high level of experts here.
public class AVLTreeMethods {
public Node root = null;
public int height(Node node){
if (node == null)
return 0;
return node.height;
}
public int max(Node node1, Node node2){
if (node1.height > node2.height)
return node1.height;
return node2.height;
}
public Node rotateRight(Node node){
Node newNode = node.left;
node.left = newNode.right;
newNode.right = node;
node.height = max(node.left,node.right) + 1;
newNode.height = max(newNode.left, newNode.right) + 1;
return newNode;
}
public Node rotateleft(Node node){
Node newNode = node.right;
node.right = newNode.left;
newNode.left = node;
node.height = max(node.left,node.right) + 1;
newNode.height = max(newNode.left, newNode.right) + 1;
return newNode;
}
public Node AVLINSERT(int data, Node root){
if (root == null){
return new Node(data);
}
else if (data > root.data){
root.left = AVLINSERT(data, root.left);
}
else if (data < root.data){
root.right = AVLINSERT(data, root.right);
}
int balance = height(root.left) - height(root.right);
if (balance > 1){
if (height(root.left.left) > height(root.left.right)){
return rotateRight(root);
}
else {
root.left = rotateleft(root.left);
return rotateRight(root);
}
}
if (balance < -1){
if (height(root.right.right) > height(root.right.left)){
return rotateleft(root);
}
else
root.right = rotateRight(root);
return rotateleft(root);
}
root.height = 1 + max(root.left, root.right);
return root;
}
public void inorderPrinting(Node root){
inorderPrinting(root.left);
System.out.println(root.data);
inorderPrinting(root.right);
}
public void callingAVLInserting(int data){
AVLINSERT(data,root);
}
public void callinInorderPrinting(){
inorderPrinting(root);
}
}
Just by looking at your code, you have initialised the root to null however, you do not have any constructor that initializes it.
So try add something of the sort.
public class AVLTreeMethods {
public Node root = null;
//add the following
public AVLTreeMethods() {
//initialize your root appropriately e.g.
this.root = new Node(//pass in some data e.g 0)
}
...rest of your code
}
My code for inserting a node into a BST is not working. When I try to display it shows only the last two nodes of the tree, i.e. it somehow overwrites the nodes in a tree. What did I do wrong? Thanks in advance!
public Node Insert(int value)
{
Node newNode = new Node();
newNode.data = value;
newNode.left = null;
newNode.right = null;
if(root == null){
root = newNode;
return root;
}
else{
while(root != null){
if(root.data < value){
if(root.right != null){
root = root.right;
}
else{
root.right = newNode;
break;
}
}
else{
if(root.left != null){
root = root.left;
}
else{
root.left = newNode;
break;
}
}
}
return root;
}
}
public void inOrder(){
inOrder(this.root);
}
private void inOrder(Node root){
if(root != null){
inOrder(root.left);
System.out.println(root.data);
inOrder(root.right);
}
}
root points to the top node of your tree. In the while you are changing its value. You must use anoter variable (say 'n').
The initial value of 'n' is 'root'.
And inside the while you only use 'n'.
if(root == null){
root = newNode;
return root;
}
else{
Node n = root;
while(n != null){
...
}
return root;
...
You must return 'root', not 'n', because the root don't change.
See my comments in the code . Hope it helps.
public Node Insert(int value)
{
Node newNode = new Node();
newNode.data = value;
newNode.left = null;
newNode.right = null;
if(root == null){
root = newNode;
return root;
}
else{
while(root != null){
if(root.data < value){
if(root.right != null){
root = root.right;
// root should point to the head of the tree.
/* Here you are changing the variable root to point to some other memory location and the reference to the head of the tree is lost. You should store the reference to the head of the tree in a temporary variable to return later */
}
else{
root.right = newNode;
break;
}
}
else{
if(root.left != null){
root = root.left;
//root should point to the head of the tree.
/* Here you are changing the variable root to point to some other memory location and the reference to the head of the tree is lost. You should store the reference to the head of the tree in a temporary variable to return later */
}
else{
root.left = newNode;
break;
}
}
}
// return temporary variable which points to the head of the tree here
return root;
}
}
public void inOrder(){
inOrder(this.root);
}
private void inOrder(Node root){
if(root != null){
inOrder(root.left);
System.out.println(root.data);
inOrder(root.right);
}
}
So i have 3 methods 1 that adds a node to the binary tree using the traverseAdd method, and another method which finds the location of where a value would be placed within the tree based on its parent node. I would like to eliminate the traverseAdd method and use the findLocation method within the add method to add the new value to the BST.
public void add(int val) {
/*Adds a new node to the binary tree after traversing the tree and figuring out where it belongs*/
Node nodeObjToAdd = new Node(val);
if(root == null){
//if node root is not null root = new node value
root = nodeObjToAdd;
}
Node nodeTraversed = root;
traverseAdd(nodeTraversed, nodeObjToAdd);
}
private void traverseAdd(Node node, Node nodeObjToAdd){
/*Traverses tree and finds a place to add the node to be added by comparing values of the left child and right child of the
* focus node*/
if(nodeObjToAdd.value < node.value){
if(node.leftChild == null){
node.leftChild = nodeObjToAdd;
}
else {
//if the val < the root.value set int he constructor
traverseAdd(node.leftChild, nodeObjToAdd);
}
}
else if(nodeObjToAdd.value > node.value) {
if (node.rightChild == null) {
node.rightChild = nodeObjToAdd;
} else {
traverseAdd(node.rightChild, nodeObjToAdd);
}
}
}
public Node findNodeLocation(Node rootNode, int val) {
/*returns where a the Node after which the value would be added.*/
if(val < rootNode.value && rootNode.leftChild != null){
return rootNode.leftChild;
}
if(val >= rootNode.value && rootNode.rightChild != null){
return rootNode.rightChild;
}
else
return this.root;
}
public void add(int val) {
if (root == null) {
root = new Node(val);
}
Node cur = root;
Node next = null;
while (true) {
next = findNodeLocation(cur, val);
if (next != cur) {
cur = next;
} else {
break;
}
}
if (val < cur.value) {
cur.leftChild = new Node(val);
} else {
cur.rightChild = new Node(val);
}
}
I think this should work