Binary tree insert - java - java

I'm trying to insert elements into binary tree, if the element is inserted it should return true and if the element is already in the tree it should return false.
Here is what i did, It doesn't give me any error message but it only returns true for the first element inserted and for the rest of them false even if they are not the same as the first element.
public static class Node {
int data;
Node left;
Node right;
Node(int d)
{data=d;
left=null;
right=null;}
}
static class BTree{
Node root;
}
static boolean insert(BTree t,int data) {
Node newNode=new Node(data);
if (t.root==null) {
t.root=newNode;
return true;
}
else {
while (t.root.data!=data) {
if (t.root.data>data)
{t.root=t.root.left; insert(t, data);}
else if (t.root.data<data)
{t.root=t.root.right; insert(t, data);}}
return false;
}
}

Your code is modifying t.root when the tree is not empty. This is wrong. During the decent through the tree, the root reference should not be changed.
Secondly, your algorithm is using both iteration (while) and recursion. But these are alternatives that you should not combine: choose either the iterative version or the recursive version.
Since your function takes a BTree instance, and there is only one such instance at play, a recursive implementation would need a different function; one that takes a Node type as argument.
Here I will just stick to the iterative idea and remove the recursion. Use a separate variable for traversing down the tree:
else {
Node node = t.root;
while (node.data != data) {
if (node.data > data) {
if (node.left == null) {
node.left = newNode;
return true;
}
node = node.left;
} else if (node.data < data) {
if (node.right == null) {
node.right = newNode;
return true;
}
node = node.right;
}
}
return false;
}

Related

How to find a Node of a Binary Search Tree without using a recursive method

If I have a Method that only takes value as an argument (not Node) called public Node finder (E val) how can I find the respective Node regardless of the height and width of the tree. If the method took Node as an argument then it would be an easy solution to use recursion. But unfortunately I am not allowed to change the method signature. How can I do this the smart way rather than the dumb way I am trying below which would just end up with a ton of embedded if functions
public class BinarySearchTree<E extends Comparable<E>> {
class Node {
E value;
Node leftChild = null;
Node rightChild = null;
Node(E value) {
this.value = value;
}
}
public Node finder(E val) {
if (val == null) return null;
if (root == null) return null;
boolean flag = false;
Node temp = root;
//find if Root Node matches value
if(temp.value.compareTo(val) == 0) {
flag = true;
return temp;
}
//if value is less than root check the left branch
else if (temp.value.compareTo(val) > 0) {
if(temp.leftChild.value.compareTo(val) == 0) {
flag = true;
return temp.leftChild;
}
//more if statements here
}
//if value is more than root check the right branch
else {
if(temp.rightChild.value.compareTo(val) == 0) {
flag = true;
return temp.rightChild;
}
//more if statements here
}
return null;
}
}
Binary search trees have this interesting property:
The left subtree of a node contains only nodes with values lesser than the node’s value.
The right subtree of a node contains only nodes with value greater than the node’s key.
Assuming your class BinarySearchTree holds a reference to the root, you can traverse the binary tree iteratively till you either reach the value or reach a leaf node which means your value does not exist in your binary search tree. The time complexity of this search operation is O(log(n)).
Here's some pseudocode
Find-Node(val):
node = root
while node != null:
if val == node.val then return root
if val < node.val then node = node.left
if val > node.val then node = node.right
return null

Binary Search tree won't add new nodes?

I am trying to write a recursive method to add a node to a binary search tree (that does not allow duplicates). For some reason, the method only works when the tree is empty, otherwise it prints out "Duplicate" (even if it is not a duplicate). I am new to programming and would appreciate help and tips to fix this. Thank you.
//add new node to the tree
public void add(int data) {
Node<Integer> newNode = new Node<>(data); //create new node with the data
//if the tree is empty, the newNode becomes the root
if (size() == 0) {
root = newNode;
return;
}
//otherwise, check if node should be placed to right or left
add(data, root);
}
private void add(int data, Node<Integer> node) {
//base case - found an empty position
if (node == null) {
node = new Node<Integer>(data);
}
if (data < node.data) {
add(data, node.left);
}
else if (data > node.data) {
add(data, node.right);
}
else if (data == node.data) {
System.out.println("Duplicate. This value cannot be added to the tree.");
}
}
When your tree is empty, the node is added properly to it. The first add(int data) function is fine.
The problem exists with the second add(int data, Node<Integer> node) function. In case if the tree already has an element, this method is called. If the node passed is either greater or lesser than the value passed then the function is called again with either the left or right child of the current node. This value might be (will eventually be) null. That leads to creation of a node in the base case of your method which leads to the satisfaction of this data == node.data condition as the node was indeed created with the data value. Hence you get the error message.
In order to fix this, the second function can be altered as below :
private void add(int data, Node<Integer> node) {
if (data < node.data) {
if (node.left != null) {
add(data, node.left);
} else {
node.left = new Node<>(data);
}
}
else if (data > node.data) {
if (node.right != null) {
add(data, node.right);
} else {
node.right = new Node<>(data);
}
add(data, node.right);
}
else if (data == node.data) {
System.out.println("Duplicate. This value cannot be added to the tree.");
}
}
See that the base case has been removed. If ever encountered the base case does not provide us with a reference to any tree node. Hence addition of data to the tree is impossible (the node argument must never be null).
Also, the code adds data as a child to node if the child is null. This guarantees that the method is not recursively with a null node argument and adds data to its rightful place more importantly.
At the end of the recursion you are not returning the actual root of the BST. "root" object that you have it is pointing to the last inserted node. So every time you are trying to insert the same value it will be inserted after the last inserted node which have the same value. Here is my implementation:
class BinarySearchTree {
class Node {
int key;
Node left, right;
public Node(int item) {
key = item;
left = right = null;
}
}
Node root;
BinarySearchTree() {
root = null;
}
void add(int data) {
root = add(root, data);
}
Node add(Node root, int data) {
if (root == null) {
root = new Node(data);
return root;
}
if (data < root.key)
root.left = add(root.left, data);
else if (data > root.key)
root.right = add(root.right, data);
else if( data==root.key) {
System.out.println("Duplicate. This value cannot be added to the tree.");
}
return root;
}
void inorder() {
inorderRec(root);
}
void inorderRec(Node root) {
if (root != null) {
inorderRec(root.left);
System.out.println(root.key);
inorderRec(root.right);
}
}
public static void main(String[] args) {
BinarySearchTree tree = new BinarySearchTree();
tree.add(50);
tree.add(30);
tree.add(20);
tree.add(20);
// print inorder traversal of the BST
System.out.println("Inorder traversal");
tree.inorder();
tree.add(40);
tree.add(40);
tree.add(70);
tree.add(60);
tree.add(80);
System.out.println("Inorder traversal");
// print inorder traversal of the BST
tree.inorder();
}
}

How to delete a node that has been found

I'm working on a binary search tree where i have to delete a node. The node has already been found, so i don't need to traverse and find the specific node. All i need is to delete a node, which is taken as an arguement.
I have started the the node remove method and currently only done how to delete a node if it has no children or is a leaf node. How do i implement a java code which will delete if it has 1 children or a parent?
my current remove method:
public void removeHelper(Node focus){
if(focus.leftChild == null && focus.rightChild == null){
focus = null;
}
// if the node has 1 child
// if the node has 2 children
}
You need to travel down the tree, because you will need to replace the root field, or either the leftChild or rightChild of the parent node.
To remove a node that has both leftChild and rightChild not null, you can replace the node with either the rightmost node of the left subtree, or the leftmost node of the right subtree.
In this example, I assume that the methods are in a class (Tree?) that have a Node field called root, and that the Nodes have a field value that is a Comparable:
public void remove(Node focus) {
root = removeHelper(root, focus);
}
public static Node removeHelper(Node root, Node focus) {
if (root == null) {
return null;
} else if (root == focus) {
if (focus.leftChild == null) {
return focus.rightChild;
} else if (focus.rightChild == null) {
return focus.leftChild;
} else {
Node node = removeLeftMostOfRight(focus);
node.leftChild = focus.leftChild;
node.rightChild = focus.rightChild;
return node;
}
} else {
int r = focus.value.compareTo(root.value);
if (r < 0) {
root.leftChild = removeHelper(root.leftChild, focus);
} else {
root.rightChild = removeHelper(root.rightChild, focus);
}
return root;
}
}
private static Node removeLeftMostOfRight(Node focus) {
Node node = focus.rightChild;
if (node.leftChild == null) {
focus.rightChild = node.rightChild;
} else {
Node prev;
do {
prev = node;
node = node.leftChild;
} while (node.leftChild != null);
prev.leftChild = node.rightChild;
}
return node;
}
Note that in languages like C/C++ you can have pointers to pointer, that allow a much simpler and more efficient implementation of binary trees.

Search Double Linked List Java Recursively

I am trying to search a doubly-linked list in Java for a term, and return it if found. Here is my code so far:
private class Node {
public String content;
public Node up;
public Node left;
public Node right;
}
private Node searchList(String term, Node node) {
while (node != null) {
System.out.print(node.name + " - "); //To see process
if (node.content.equals(term)) {
return node;
} else if (node.right != null) {
return searchList(term, node.right);
}
node = node.left;
}
return null;
}
My algorithm is basically:
While the node is not null
Check if it matches the search term
If there is an element to he right, scan that with recursion
Both points are now null, item is not present
Edit with my question, sorry:
I cannot get it to search down to bottom levels and having trouble understanding where I have gone wrong.
Any help would be appreciated!
I got to agree with the comments that your question is unclear.
However, I assume you are just looking for a way to implement a recursive search on a double linked list (in which null elements are not allowed). As the other answer already mentions, I assume type Page to be a subtype of Node. In fact, I will substitute it in my example below.
Since there seems to be some misconception about implementing a double linked list and about recursion itself, I will give a condensed but running example.
The code you are presenting lacks a termination condition for the recursion. Which, unfortunately, also holds true for ikicha's solution. One way (amongst others) to accomplish this is to use a helper method to pass an invariant (eg. the start element) or counter from one iteration of the recursion to the next one.
The line node = node.left in your example has no effect. If you wanted to achieve a search in both directions (as ikicha sketched) I would be interested in why direction matters for you.
public class DoubleLinked {
private Node first;
private Node last;
private int size;
private class Node {
public String content;
public Node left;
public Node right;
public Node(String content) {
this.content = content;
}
}
private void addElement(Node addedNode) {
if (first == null) {
first = addedNode;
last = addedNode;
} else {
last.right = addedNode;
addedNode.left = last;
addedNode.right = first;
last = addedNode;
}
size++;
}
private Node searchList(String term, Node node) {
int tries = 0;
if (node != null) {
return searchHelper(term, node.right, tries);
}
return null;
}
private Node searchHelper(String term, Node node, int tries) {
if (node == null || tries >= size) {
return null;
}
if (node.content.equals(term)) {
return node;
} else {
return searchHelper(term, node.right, tries);
}
}
public static void main(String[] args) {
DoubleLinked list = new DoubleLinked();
list.addElement(list.new Node("first"));
Node startNode = list.new Node("second");
list.addElement(startNode);
list.addElement(list.new Node("third"));
list.addElement(list.new Node("forth"));
Node r = list.searchList("forth", startNode);
System.out.println(r!=null?r.content:"term not found");
}
}
I think your algorithm computes same node several times because move left and find all right nodes of the left one repeatedly.
You can find node by search two direction each from start node.
private Node internalSearchList(String term, Node node, int direction) {
if (node == null) {
return null;
}
if (term.equals(node.content)) {
return node;
} else {
return internalSearchList(term, direction == 0 ? node.left : node.right, direction);
}
}
private Node searchList(String term, Node node) {
// search to left side
Node result = internalSearchList(term, node, 0);
if (result != null) {
return result;
} else {
return internalSearchList(term, node, 1);
}
}
And also I think the type of Node.left and Node.right must be Node.
private class Node {
public String content;
public Node up;
public Node left;
public Node right;
}

Node not added to tree

I've been trying to create a integer binary search tree with Java and for some reason, I've been going wrong with adding new nodes to the tree.
Here is the NODE class.
class NODE
{
NODE left = null, right = null;
int info;
public NODE(int x)
{
info = x;
}
}
and here's the BST(Binary Seatch Tree) class with the insert() method.
class BST
{
NODE tree = null;
public void insert(int x)
{
NODE node = new NODE(x);
NODE temp = tree;
while(true)
{
if(temp == null)
{
temp = node;
break;
}
else if(temp.info > x) temp = temp.left;
else temp = temp.right;
}
}
//other methods present here
}
For reasons that I could not figure out, the insert() method is going wrong.
The object tree carries null in it even after the insert() method is called.
Can you find something spotty in the code?
Thanks!
Use a recursive insert method in the NODE class (instead of utilizing an infinite loop as you did):
public void insert(int x) {
if(x < this.info) {
if(this.left == null)
this.left = new NODE(x);
else
this.left.insert(x);
}
else {
if(this.right == null)
this.right = new NODE(x);
else
this.right.insert(x);
}
}
And your BST class would have the following insert method (simply calls the other insert method):
public void insert(int x) {
if(tree == null)
tree = new NODE(x);
else
tree.insert(x);
}
The main insert method is in the NODE class because it must recursively call itself on nodes within the tree.
Of course tree remains null - you don't assign anything to this field.
After temp = tree; and temp = node; only temp is changed, not tree.
The insert() method should insert the child of a node into the tree, calling an already declared Node as a parameter. e.g.:
//Returns true/false depending on whether the insert is successful
public boolean insert(int x, Node node, boolean leftChild) {
if (node == null) return false;
Node child = new Node(x);
if (leftChild) {
if (node.left != null) return false;
node.left = child;
} else {
if (node.right != null) return false;
node.right = child;
}
return true;
}

Categories

Resources