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);
}
}
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.
Why am I getting false while doing search(7)?
I tried recursive solution its working fine..
tried implementing with loop failed
public class BST {
class Node {
int data;
Node left , right;
public Node(int data) {
this.data = data;
this.left = this.right = null;
}
}
Node root;
public BST() {
this.root = null;
}
public void insert(int data) {
// create a new node and start iteration from root node
Node newNode = new Node(data);
Node currentNode = this.root;
while (true) {
if (currentNode == null) {
currentNode = newNode;
break;
}
if (data < currentNode.data) { // if data is less go left
currentNode = currentNode.left;
} else if (data > currentNode.data) { // if data is greater go right
currentNode = currentNode.right;
} else { // do nothing for duplicates
break;
}
}
}
public boolean search(int data) {
Node currentNode = this.root;
while (true) {
if (currentNode == null) {
return false;
}
if (data == currentNode.data) {
return true;
} else if (data < currentNode.data) {
currentNode = currentNode.left;
} else {
currentNode = currentNode.right;
}
}
}
public static void main(String... args) {
BST tree = new BST();
tree.insert(15);
tree.insert(7);
System.out.println(tree.search(7));
}
}
Problem is inside the insert method - you are not inserting the nodes correctly inside the tree.
If the tree is empty, you should assign to this.root, not currentNode. Assigning to currentNode has no affect on this.root.
Currently, your code isn't inserting any node inside the tree; it simply assigns the new node to the local variable of insert method, i.e. currentNode.
If the condition data < currentNode.data is true, then you need to check if the currentNode.left is null or not. If it is, then link the new node with the current node as shown below:
currentNode.left = newNode;
If currentNode.left is not null, then do the following:
currentNode = currentNode.left;
Currently, your code moves the currentNode to null and then assigns the newNode to the currentNode without a reference to its parent node in the tree.
Do step 2 for data > currentNode.data as well.
Change the implementation of the insert method as shown below:
public void insert(int data) {
Node newNode = new Node(data);
if (this.root == null) {
this.root = newNode;
return;
}
Node currentNode = this.root;
while (true) {
if (data < currentNode.data) {
if (currentNode.left == null) {
currentNode.left = newNode;
} else {
currentNode = currentNode.left;
}
} else if (data > currentNode.data) {
if (currentNode.right == null) {
currentNode.right = newNode;
} else {
currentNode = currentNode.right;
}
} else {
break;
}
}
}
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
}
I am trying to insert node in a binary tree using recursive method. But once its out of the method the root becomes the new node and left child and right child are null. With this I'm trying to learn how recursion works. Also, does recursive method always has to return something. Below is the code.
public class BinaryNode {
int key;
BinaryNode left;
BinaryNode right;
public BinaryNode( int key){
this.key = key;
// this.left = left;
//this.right = right;
}
}
public class BinaryTree {
BinaryNode root;
public void insert(int key){
BinaryNode newNode = new BinaryNode(key);
if(root == null){
root = newNode;
}else{
BinaryNode focusNode = root;
BinaryNode parent;
while(true){
parent = focusNode;
if(key<focusNode.key){
focusNode = focusNode.left;
if(focusNode==null){
parent.left= newNode;
return;
}
}else{
focusNode = focusNode.right;
if(focusNode==null){
parent.right= newNode;
return;
}
}
}
}
}
public BinaryNode recursiveInsert(int key, BinaryNode node){
BinaryNode newNode = new BinaryNode(key);
if (node == null){
root = newNode;
}
else{
if(key < node.key){
root.left = recursiveInsert(key, node.left);
}
else{
root.right = recursiveInsert(key, node.right);
}
}
return root;
}
public String toString(){
String toTree = null;
return toTree;
}
public static void main(String[]args){
BinaryTree tree = new BinaryTree();
tree.recursiveInsert(7, tree.root);
tree.recursiveInsert(6, tree.root);
tree.recursiveInsert(4, tree.root);
tree.recursiveInsert(8, tree.root);
tree.recursiveInsert(9, tree.root);
tree.recursiveInsert(5, tree.root);
}
}
The method I'm trying is recursiveInsert. Thanks!!
I suppose the problem comes from
if (node == null){
root = newNode;
}
You are traversing the tree and in the last step you are asking the left/right child of a leaf node. This hasn't one, so it's child is null.
This is the value returned by the recursive calls and in the end, it gets assigned to root.
To fix this, before descending into a node, make sure that child node exists.
Also this is a bit weird
root.left = recursiveInsert(key, node.left);
It should be node and not root.
There are several issues with your code which I won't necessarily go into, because I think they distract from your core questions.
To answer your second question first: No, there's no rule that says that recursive methods have to return anything. It's more important that they know when to terminate.
As for your bug, I think it's probably due to the fact that your insert method always returns and operates on root. You probably mean to modify and return newNode.
This is because your recursiveInsert method always operates on root. Try this instead -
public Node recursiveInsert(Node currentParent, Node newNode) {
if (currentParent == null) {
return newNode;
} else if (newNode.key > currentParent.key) {
currentParent.right = recursiveInsert(currentParent.right, newNode);
} else if (newNode.key < currentParent.key) {
currentParent.left = recursiveInsert(currentParent.left, newNode);
}
return currentParent;
}
Your recursive code should be like this :
public BinaryNode recursiveInsert(int key, BinaryNode node) {
if (node == null) {
return root = new BinaryNode<>(key);
} else {
if (key < node.key) {
if (node.left == null) {
return node.left = newNode;
} else {
return recursiveInsert(key, node.left);
}
} else {
if (node.right == null) {
return node.right = newNode;
} else {
return recursiveInsert(key, node.right);
}
}
}
}
You are acting on root node in your recursive function, you should rather be acting on the node passed to the recursive function.
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