Delete from Binary Search Tree in Java - java

I can't find what is wrong with my deletion algorithm. When I run my delete method on the root of the BST, it will replace the root with the value of the minimum of the right subtree, but it is not deleting the node thereafter.
public void delete(BinaryTreeNode node, int x){
if (node==null)
return;
else if (x<node.getKey())
delete(node.getLeftChild(),x);
else if (x>node.getKey())
delete(node.getRightChild(),x);
else{
if (node.getLeftChild()==null)
node = node.getRightChild();
else if (node.getRightChild()==null)
node = node.getLeftChild();
else{
BinaryTreeNode temp = findMin(node.getRightChild());
System.out.println(temp.getKey() + " " + node.getKey());
node.setKey(temp.getKey());
System.out.println(temp.getKey() + " " + node.getKey());
delete(node.getRightChild(), node.getKey());
}
}
}
and my findMin() method:
public BinaryTreeNode findMin(BinaryTreeNode node){
if (node.getLeftChild()==null)
return node;
else
return findMin(node.getLeftChild());
}
For a BST containing all integers 1-9 with a root of 4, my output for inorderPrint() yields
1,2,3,5,5,6,7,8,9
instead of
1,2,3,5,6,7,8,9

Update your deleted-node's parent's pointer with the correct node. You need to get rid of any traces of the deleted node. Have a temporary node to keep track of the parent node, so this is easier to do once you find the node to delete.

When you are setting node = node.getLeftChild(); (or symetrically node = node.getRightChild(); you are changing the value of the local variable node, and not the reference to this node from the father.
You are missing something like:node.father.left = ....(or node.father.right = ...).
You should change the values in the tree itself, and not only the references you hold in the method.

Related

binary tree insertion using recursion (clarification)

I have the following code to insert into the binary tree:
public void insert(T item) {
root = insert(item, root);
}
private Node insert(T item, Node node) {
if(node == null){
return new Node(item, null, null);
} else {
if(item.compareTo(node.item) > 0) {
node.rightChild = insert(item, node.rightChild);
} else {
node.leftChild = insert(item, node.leftChild);
}
}
return node;
}
the code works fine, I have tested it
my question is, how come the root is never changed since in the public function I assigned the returned node from the private function to the root
Thank you!
The public insert is just an interface into the recursive method which rebuilds the tree as the stack unwinds ending where you started, at the root (root = ...). Except for the first insert, you go left or right until you insert at the leaf level. Without any balancing, you will have the same root (assuming no removals) for the lifetime of the tree. Therefore, the only time the root changes on insert is when it's empty.
Note: There's also a matter of what happens when a node is inserted with an existing value; do you discard it, allow duplicates, or swap the objects? That's an implementation detail.
I read your code again and your code is correct. The return value is always the root element because your frist function call is insert(item, root) and the return value is what you give.

Binary Search tree - insertion

You are given a pointer to the root of a binary search tree and a value to be inserted into the tree. Insert this value into its appropriate position in the binary search tree and return the root of the updated binary tree. You just have to complete the function.
I have given my code but one test case is not working. Here is my code:
static Node Insert(Node root,int value){
Node d =root;
Node q = new Node();
q.left = null;
q.right=null;
q.data = value;
while(true){
if(value<d.data){
if(d.left==null){d.left = q;
return root; }
else{
d= d.left ;
}
}
else{
if(value>d.data){
if(d.right==null){d.right=q;
return root;}
else d = d.right;
}
}
}
}
You're missing two cases: value == d.data and the empty tree.
value == d.data: In that case the tree won't be altered in any way, but your code won't break-off and end up in an infinite loop.
Simplest solution would be to insert these lines in the while-loop:
if(value == d.data)
return root;
The case where the tree is empty is rather implementation-specific, so it's difficult to suggest any solution for this case.

why i got this message[“Variable name” cannot be resolved to a variable]?

I am writing a code about finding the parent for a specified node (in BST). I wrote it but it doesn't work! I use Eclipse using Java,and i get this error:
"parent" cannot be resolved to a variable.
i wonder how to solve this problem? (i am kinda new to java, thanks in advance)
There is my code:
public TreeNode<E> getParent(TreeNode<E> node) {
TreeNode<E> parent = null;
TreeNode<E> current = root;
while (current != null) {
if (((Comparable<E>)node).compareTo((E)current) < 0) {
parent = current;
current = current.left;
} else if (((Comparable<E>) node).compareTo((E)current) > 0) {
parent = current;
current = current.right;
} else {
break;
}
}
size++;
return parent;
}
As per your comment, "it appear when i wrote: System.out.print("\nthe parent of" + list.search(5) + parent)" and the fact, that this line does not appear in the method that you posted in your question, the conclusion is:
You are trying to access a method's local variable in another place - for example in another method. You should learn about scope. Search for it. Good starting point is the link in Aniket's comment.
Quick solution to your problem: It seems that you want to print a parent of a specific node in your tree. Therefore you already wrote the method getParent that returns exactly that parent. You cannot access the parent variable (because it is known only during the method's execution), but you can use the method's return value:
TreeNode node = list.search(5); // didn't use type parameter here
System.out.print("The parent of " + node + ": " + getParent(node));

Adding an element a binary search tree

Trying to add an element to BST. I have an idea of how to do it, but my implementation is destructive, and the original root is not preserved (so the tree basically becomes useless). The tree is based on lists, and this method is based on recursion. My real problem is preserving the original root. I'm using generics.
So far what I have:
public void addElement(E elem, Node<E> root) {
Create node with a value of elem, call it newNode
Case 1: Tree is empty
root = newNode();
return; //End of method.
Otherwise, keep searching the tree (by comparing the value of out node a with the root of the tree.
if (!root.hasLeft() && !root.hasRight) { //if the root in question has no children
if (elem < rootValue) { //Set the element as the left element
root.setLeft(newNode);
}
else { //Set the element as the right element.
root.setRight(newNode);
}
}
else {
if (E < root.getElem()) {
//This is where the value of our node is compared to the value of the root, which we passed in.
//(I know that we can't use the < and > operators with generics, but assume it works).
root = root.getLeft() //Left node is new root
addElement(elem, root); //Call the method again
}
else {
root = root.getRight(); //Right node is new root
addElement(elem, root) //Call method again
}
}
}
Forgive me if this is a duplicate/vague question, this is my first post on SO, and I'm kind of noob.
if (!root.hasLeft() && !root.hasRight) {
This logic is wrong. You're only considering "setting" the left child, if you have neither a left nor right child. This change should do it:
void addElement(elem, root)
{
if (elem < root.value) {
if(!root.hasLeft())
root.setLeft(newNode);
else
addElement(elem, root.getLeft());
}
else {
if(!root.hasRight())
root.setRight(newNode);
else
addElement(elem, root.getRight());
}
}
You should not be changing root of the class, just passing it into the next method call. This should preserve root.
By the way, I assume you have rootValue = root.value somewhere or somethign similar?

Using recursively returned reference to node in tree does not allow changes to the node itself

My data structures class is working with trees. We are implementing a 3-ary tree, containing 2 values with a reference to a left, middle, and right node (left subtree is less than value 1, middle subtree is between value 1 and value 2, right subtree is greater than value 2). An interface has been provided for the Tree class, and the find, insert, and delete methods must be recursive. The client code which this will be tested against uses the insert method repeatedly to create the tree, and the root starts off as null.
I'm trying to insert values into the tree recursively by finding the parent node in a separate private method, then changing the returned node as appropriate. The problem currently is that the method returns the initial node, which is the root, and correctly creates a new node with the value because the root is null. However, the root remains null.
I'm pretty certain this is due to the way that references and values work in Java (similar to C# as described in this article by Jon Skeet); given the constraints, how should I change this to allow insertions into the tree? Below is the current insert method in the tree class, along with the similar private method.
public void insert(AnyType newData)
{
// If insert node is null, make a new node with newData as first key
TernaryNode<AnyType> insert_node = findNode(newData, root);
if (insert_node == null)
{
insert_node = new TernaryNode<AnyType>(newData);
}
else
{
// Get the key that is equal if the insert node is not null
if (insert_node.getKey1() == null)
{
insert_node.setKey1(newData);
}
else
{
insert_node.setKey2(newData);
}
}// end else
}// end insert
private TernaryNode<AnyType> findNode(AnyType item, TernaryNode<AnyType> node)
{
TernaryNode<AnyType> current_node = node;
if (current_node != null)
{
if (current_node.getKey1() != item &&
current_node.getKey2() != item)
{
// Comparator checks left
if (compare.compare(current_node.getKey1(), item) <= -1)
{
return findNode(item, current_node.left);
} // Comparator checks right
else if (compare.compare(current_node.getKey2(), item) >= 1)
{
return findNode(item, current_node.right);
}// Comparator checks middle
else
{
return findNode(item, current_node.middle);
}
}// end while
}// end if
// Return current node even if it is null
return current_node;
}// end findNode
Unless you're assigning something to the root member, it will never acquire a value. You probably need some sort of outer container for your tree, similarly to how an XML document (which is also a tree) has an outer Document object which is distinct from the actual document root node.
TernaryNode<AnyType> insert_node = findNode(newData, root);
if (insert_node == null)
{
insert_node = new TernaryNode<AnyType>(newData);
root = insert_node;
}

Categories

Resources