I am making a boolean method that Deletes an element from the binary tree,
Returns true if the element is deleted successfully
, and Returns false if the element is not in the tree. The issue that I am having is that for some reason it is not deleting the node sometimes. I just want to know if I am doing anything wrong, thanks in advance.
here is my code:
public boolean delete(E e) {
BSTDelete<E> d = new BSTDelete<E>();
boolean deleted = d.delete(e, root);
if (deleted)
size -= 1;
return deleted;
}
public class BSTDelete<E extends Comparable<E>> {
public boolean delete(E e, TreeNode<E> root) {
if (root == null) {
return false;
}
if (e == root.element) {
if (root.right == null && root.left == null) {
root = null;
} else if (root.right == null) {
root = root.left;
} else if (root.left == null) {
root = root.right;
} else
root.element = minValue(root.left);
delete(root.element, root.left);
// Delete the inorder successor
} else if (e.compareTo(root.element) < 0) {
delete(e, root.left);
} else {
delete(e, root.right);
}
return true;
}
E minValue(TreeNode<E> root) {
E minv = root.element;
while (root.right != null) {
minv = root.right.element;
root = root.right;
}
return minv;
}
}
here is a test that keeps failing. The second assertEquals says that i.next() is "Beatrice" and not "Carl"
BST <String>b = new BST<String>();
b.insert("Arthur");
b.insert("Beatrice");
b.insert("Carl");
b.insert("Dagmar");
b.delete("Beatrice");
Iterator <String> i = b.iterator();
assertEquals(i.next(), "Arthur");
assertEquals(i.next(), "Carl");
assertEquals(i.next(), "Dagmar");
}
and here is my BSTInorderIterator class:
public class BSTInorderIterator<E extends Comparable<E>> implements
java.util.Iterator<E> {
int current = 0;
ArrayList<E> list = new ArrayList<E>();
private TreeNode<E> root;
public BSTInorderIterator(TreeNode<E> root) {
list = new ArrayList<E>();
inorder(root);
}
/** Inorder traversal from the root */
public void inorder() {
inorder(root);
}
/** Inorder traversal from a subtree */
public void inorder(TreeNode<E> root) {
if (root.left != null)
inorder(root.left);
list.add(root.element);
if (root.right != null)
inorder(root.right);
}
#Override
/** More elements for traversing? */
public boolean hasNext() {
return current < list.size();
}
#Override
/** Get the current element and move to the next */
public E next() {
return list.get(current++);
}
#Override
/** Remove the current element */
public void remove() {
// to do: make this work correctly
}
The delete method inside the class BSTDelete is a recursive method, however you're never returning the recursive method calls. Therefore your delete method will only ever return false when you call it with a like d.delete(e, root) where root is null.
For example even though delete(e, root.left) might return false because root.left is null your original method call will return true since you don't return the result of delete(e, root.left).
To fix this add return when you're calling the method recursively, this might only be a partial fix to your issue:
public boolean delete(E e, TreeNode<E> root) {
if (root == null) {
return false;
}
if (e == root.element) {
if (root.right == null && root.left == null) {
root = null;
} else if (root.right == null) {
root = root.left;
} else if (root.left == null) {
root = root.right;
} else
root.element = minValue(root.left);
return delete(root.element, root.left);
// Delete the inorder successor
} else if (e.compareTo(root.element) < 0) {
return delete(e, root.left);
} else {
return delete(e, root.right);
}
return true;
}
Related
I need help with following Code:
public boolean remove(Integer value) {
if (isEmpty()) {
throw new NoSuchElementException();
}
if (!isEmpty()) {
if (head == tail) {
head = tail = null;
}
} else {
}
size--;
return false;
}
And this is my task:
"removes the first occurrence of the specified value from this list"
It s a method of a Doubly Linked List.
So far I think I did correct but I am still missing the "else" part and I have no clue what to put inside...
I also have a class with a constructor and getter- and setter- methods.
Here is my node class:
public class ListElement {
private Integer value;
private ListElement next;
private ListElement prev;
public ListElement(ListElement prev, Integer value, ListElement next) {
this.value = value;
this.next = next;
this.prev = prev;
}
public Integer getValue() {
return value;
}
public ListElement getNext() {
return next;
}
public ListElement getPrev() {
return prev;
}
public void setValue(Integer value) {
this.value = value;
}
public void setNext(ListElement next) {
this.next = next;
}
public void setPrev(ListElement prev) {
this.prev = prev;
}
}
I am assuming by the function signature that you want to delete the element with the specific value. You need to find that node and remove it:
public boolean remove(Integer value) {
if (isEmpty()) {
throw new NoSuchElementException();
}
ListElement found = head;
// Try to find it
while (null != found && !found.value.equals(value)) {
found = found.next;
}
// Not found?
if (null == found) {
throw new NoSuchElementException();
}
// Found. Unlink
if (found.prev != null) found.prev.next = found.next;
else head = found.next;
if (found.next != null) found.next.prev = found.prev;
else tail = found.prev;
size--;
return true;
}
Firstly, this if should be removed as you already test for empty
if (!isEmpty()) {
if (head == tail) {
head = tail = null;
}
} else {
}
Then you can process like:
public boolean remove(Integer value) {
if (isEmpty()) {
throw new NoSuchElementException();
}
if (head == tail) {
if (head.getValue() == value) {
head = tail = null;
} else {
// Not found, return false
size--;
return false;
}
}
ListElement current = head;
while (current != null) {
if (current.getValue() == value) {
// Found
if (current.getPrev() == null) {
// current node is head node
head = current.getNext();
current.setPrev(null);
} else if (current.next() == null) {
// current node is tail node
tail = current;
current.setNext(null);
} else {
// Current node is in the middle
ListElement prev = current.getPrev();
ListElement next = current.getNext();
prev.setNext(next);
next.setPrev(prev);
}
size--;
return true;
}
}
// Not found
size--;
return false;
}
So I have to modify the BST class to include a PrintRange function, which would essentially print all nodes between two values in order.
Here is the class
/** Source code example for "A Practical Introduction to Data
Structures and Algorithm Analysis, 3rd Edition (Java)"
by Clifford A. Shaffer
Copyright 2008-2011 by Clifford A. Shaffer
*/
import java.lang.Comparable;
/** Binary Search Tree implementation for Dictionary ADT */
class BST<Key extends Comparable<? super Key>, E>
implements Dictionary<Key, E> {
private BSTNode<Key,E> root; // Root of the BST
int nodecount; // Number of nodes in the BST
/** Constructor */
BST() { root = null; nodecount = 0; }
/** Reinitialize tree */
public void clear() { root = null; nodecount = 0; }
/** Insert a record into the tree.
#param k Key value of the record.
#param e The record to insert. */
public void insert(Key k, E e) {
root = inserthelp(root, k, e);
nodecount++;
}
// Return root
public BSTNode getRoot()
{
return root;
}
/** Remove a record from the tree.
#param k Key value of record to remove.
#return The record removed, null if there is none. */
public E remove(Key k) {
E temp = findhelp(root, k); // First find it
if (temp != null) {
root = removehelp(root, k); // Now remove it
nodecount--;
}
return temp;
}
/** Remove and return the root node from the dictionary.
#return The record removed, null if tree is empty. */
public E removeAny() {
if (root == null) return null;
E temp = root.element();
root = removehelp(root, root.key());
nodecount--;
return temp;
}
/** #return Record with key value k, null if none exist.
#param k The key value to find. */
public E find(Key k) { return findhelp(root, k); }
/** #return The number of records in the dictionary. */
public int size() { return nodecount; }
private E findhelp(BSTNode<Key,E> rt, Key k) {
if (rt == null) return null;
if (rt.key().compareTo(k) > 0)
return findhelp(rt.left(), k);
else if (rt.key().compareTo(k) == 0) return rt.element();
else return findhelp(rt.right(), k);
}
/** #return The current subtree, modified to contain
the new item */
private BSTNode<Key,E> inserthelp(BSTNode<Key,E> rt,
Key k, E e) {
if (rt == null) return new BSTNode<Key,E>(k, e);
if (rt.key().compareTo(k) > 0)
rt.setLeft(inserthelp(rt.left(), k, e));
else
rt.setRight(inserthelp(rt.right(), k, e));
return rt;
}
/** Remove a node with key value k
#return The tree with the node removed */
private BSTNode<Key,E> removehelp(BSTNode<Key,E> rt,Key k) {
if (rt == null) return null;
if (rt.key().compareTo(k) > 0)
rt.setLeft(removehelp(rt.left(), k));
else if (rt.key().compareTo(k) < 0)
rt.setRight(removehelp(rt.right(), k));
else { // Found it
if (rt.left() == null) return rt.right();
else if (rt.right() == null) return rt.left();
else { // Two children
BSTNode<Key,E> temp = getmin(rt.right());
rt.setElement(temp.element());
rt.setKey(temp.key());
rt.setRight(deletemin(rt.right()));
}
}
return rt;
}
private BSTNode<Key,E> getmin(BSTNode<Key,E> rt) {
if (rt.left() == null) return rt;
return getmin(rt.left());
}
private BSTNode<Key,E> deletemin(BSTNode<Key,E> rt) {
if (rt.left() == null) return rt.right();
rt.setLeft(deletemin(rt.left()));
return rt;
}
private void printhelp(BSTNode<Key,E> rt) {
if (rt == null) return;
printhelp(rt.left());
printVisit(rt.element());
printhelp(rt.right());
}
private StringBuffer out;
public String toString() {
out = new StringBuffer(400);
printhelp(root);
return out.toString();
}
private void printVisit(E it) {
out.append(it + "\n");
}
public void printPreOrder(BSTNode<E, E> root) {
if (root != null) {
System.out.println(root.element());
printPreOrder(root.left());
printPreOrder(root.right());
}
}
public void printInOrder(BSTNode<E, E> root) {
if (root != null) {
printInOrder(root.left());
System.out.println(root.element());
printInOrder(root.right());
}
}
public void printPostOrder(BSTNode<E, E> root) {
if (root != null) {
printPostOrder(root.left());
printPostOrder(root.right());
System.out.println(root.element());
}
}
}
Here's what I have so far for the PrintRange function:
public void printRange(BSTNode<E, E> root, E low, E high) {
if (root != null) {
printRange(root.left(), low, high);
if (root.element().toString().compareTo(low.toString()) > 0 && root.element().toString().compareTo(high.toString()) < 0)
System.out.println(root.element());
printRange(root.right(), low, high);
}
}
But it's giving me an error. Any suggestions on how to compare elements/nodes/I'm not even certain in a BST?
Here's the driver if it helps
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class Lab8a {
public static void main(String[] args) {
BST<String, String> tree = new BST<String, String>();
Scanner fileScan = null, scan = new Scanner(System.in);
//Open file
try {
fileScan = new Scanner(new File("inventory.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//Reads elements from file
while (fileScan.hasNextLine()) {
String s = fileScan.nextLine();
tree.insert(s, s);
}
System.out.println("\nRange");
tree.printRange(tree.getRoot(), "A", "B");
}
}
And the text file:
CT16C1288B
DT14B1225F
MI15B1250A
MI15B1251A
HO03N1095A
HY07D1095BQ
KI04D2593C
DG12A1240AQ
HY03G2593BQ
TO30A1310A
HO03N1095AQ
HO01H1351C
HO01H1350C
FT18A1288B
LR15A1000A
BM12E1000A
VW02B3113A
NI23H1230AQ
LX03D2503A
LX03D2502A
LX03D2502A
VW22A3113B
VW22B3113A
I was mistaken. There was no error. I must have fixed the code at some point.
My try (gave me a NullPointerException):
public Karte giveFirst(BinarySearchTree<Karte> t){
if(t.getLeftTree() != null) {
return giveFirst(t.getLeftTree());
}else{
return t.getContent();
}
}
Complete Binary Search Tree Code:
package Model;
private class BSTNode<CT extends ComparableContent<CT>> {
private CT content;
private BinarySearchTree<CT> left, right;
public BSTNode(CT pContent) {
this.content = pContent;
left = new BinarySearchTree<CT>();
right = new BinarySearchTree<CT>();
}
}
private BSTNode<ContentType> node;
public BinarySearchTree() {
this.node = null;
}
public void insert(ContentType pContent) {
if (pContent != null) {
if (isEmpty()) {
this.node = new BSTNode<ContentType>(pContent);
} else if (pContent.isLess(this.node.content)) {
this.node.left.insert(pContent);
} else if(pContent.isGreater(this.node.content)) {
this.node.right.insert(pContent);
}
}
}
public BinarySearchTree<ContentType> getLeftTree() {
if (this.isEmpty()) {
return null;
} else {
return this.node.left;
}
}
public ContentType getContent() {
if (this.isEmpty()) {
return null;
} else {
return this.node.content;
}
}
public BinarySearchTree<ContentType> getRightTree() {
if (this.isEmpty()) {
return null;
} else {
return this.node.right;
}
}
public void remove(ContentType pContent) {
if (isEmpty()) {
return;
}
if (pContent.isLess(node.content)) {
node.left.remove(pContent);
} else if (pContent.isGreater(node.content)) {
node.right.remove(pContent);
} else {
if (node.left.isEmpty()) {
if (node.right.isEmpty()) {
node = null;
} else {
node = getNodeOfRightSuccessor();
}
} else if (node.right.isEmpty()) {
node = getNodeOfLeftSuccessor();
} else {
if (getNodeOfRightSuccessor().left.isEmpty()) {
node.content = getNodeOfRightSuccessor().content;
node.right = getNodeOfRightSuccessor().right;
} else {
BinarySearchTree<ContentType> previous = node.right
.ancestorOfSmallRight();
BinarySearchTree<ContentType> smallest = previous.node.left;
this.node.content = smallest.node.content;
previous.remove(smallest.node.content);
}
}
}
}
public ContentType search(ContentType pContent) {
if (this.isEmpty() || pContent == null) {
return null;
} else {
ContentType content = this.getContent();
if (pContent.isLess(content)) {
return this.getLeftTree().search(pContent);
} else if (pContent.isGreater(content)) {
return this.getRightTree().search(pContent);
} else if (pContent.isEqual(content)) {
return content;
} else {
return null;
}
}
}
private BinarySearchTree<ContentType> ancestorOfSmallRight() {
if (getNodeOfLeftSuccessor().left.isEmpty()) {
return this;
} else {
return node.left.ancestorOfSmallRight();
}
}
private BSTNode<ContentType> getNodeOfLeftSuccessor() {
return node.left.node;
}
private BSTNode<ContentType> getNodeOfRightSuccessor() {
return node.right.node;
}
}
How can I change/rewrite my code for it to work?
Think what would happen when you reach the left most leaf node.
Its left tree will be null which means you will break out of the while loop. You are returning null after this and so any attempt to access the state of the return value will throw an exception.
You must return this node when it has no more left children as that will be the smallest element in the tree
Also, I don't know why you have BinarySearchTree and BSTNode. A BSTNode should be good enough to construct a tree. Please go through some tutorial/lessons for a better understanding.
How to get the first element when going through a binary search tree with inorder?
Keep going left till you can't go left anymore... If a node has a left child, go for it. Keep doing this till you get to a node that does not have a left child. When you are there, you know you are in the left-most part of the tree. Following code snippet shows an idea of how this can be achieved given the root of a BST.
public BSTNode getSmallest(BSTNode root) {
if(root.left != null)
return getSmallest(root.left);
return root;
}
I'm having an issue with implementing this BinarySearchTree listed below. For some context, I'm creating a binary search tree based off of an interface that requires generics and a comparable key.I think that there is a logic error in the code that is stumping me and it's in the insert method in the BinarySearchTree, but I'm not 100% sure.
Below is the class for my Node, which is used in my BST.
public class MyNodeClass<Key extends Comparable<Key>, Value>{
private Key key;
private Value value;
private MyNodeClass<Key,Value> left = null;
private MyNodeClass<Key,Value> right = null;
public MyNodeClass(Key key, Value val)
{
this.key = key;
this.value = val;
}
public void setKey(Key key){
this.key = key;
}
public void setValue(Value value){
this.value = value;
}
public Key getKey(){
return this.key;
}
public Value getValue(){
return this.value;
}
public void setLeft(MyNodeClass<Key, Value> l){
this.left = l;
}
public void setRight(MyNodeClass<Key, Value> r){
this.right = r;
}
public MyNodeClass<Key,Value> getLeft(){return this.left;}
public MyNodeClass<Key,Value> getRight(){return this.right;}
public int compareTo(Key that){
return(this.getKey().compareTo(that));
}
}
public class MyBinarySearchTree<Key extends Comparable<Key>, Value> implements BinarySearchTree<Key,Value> {
private MyNodeClass<Key, Value> root;
public MyBinarySearchTree(){
root = null;
}
#Override
public boolean isEmpty() {
return root == null;
}
#Override
public Value insert(Key key, Value val) {
MyNodeClass<Key,Value> newNode = new MyNodeClass<Key,Value>(key,val);
newNode.setKey(key);
newNode.setValue(val);
if(root==null){
root = newNode;
return(newNode.getValue());
}
else{
MyNodeClass<Key,Value> current = newNode;
MyNodeClass<Key,Value> parent;
while(true){
{
parent = current;
if(current.compareTo(key) == 1)
{
current = current.getLeft();
if(current == null)
{
parent.setLeft(newNode);
return parent.getLeft().getValue();
}
}
else if(current.compareTo(key) == -1){
current = current.getRight();
if(current == null)
{
parent.setRight(newNode);
return parent.getRight().getValue();
}
}
else{
if(current.compareTo(key) == 0){
current.setKey(key);
current.setValue(val);
return current.getValue();
}
}
}
}
}
}
#Override
public Value find(Key key) {
MyNodeClass<Key, Value> current = root;
while (current.compareTo(key) != 0)
{
if (current.compareTo(key) == 1)
{
current = current.getLeft();
} else {
current = current.getRight();
}
if(current == null)
return null;
}
return current.getValue();
}
#Override
public Value delete(Key key) {
MyNodeClass<Key,Value> current = root;
MyNodeClass<Key,Value> parent = root;
boolean isLeftChild = true;
while(current.compareTo(key) != 0) {
parent = current;
if (current.compareTo(key) == 1) {
isLeftChild = true;
current = current.getLeft();
} else {
isLeftChild = false;
current = current.getRight();
}
if(current == null)
return null;
}
if(current.getLeft() == null && current.getRight() == null) {
if (current == root) {
root = null;
} else if (isLeftChild) {
parent.setLeft(null);
} else{
parent.setRight(null);
}
return current.getValue();
}
else if(current.getRight() == null)
{
if(current == root) {
root = current.getLeft();
}
else if(isLeftChild) {
parent.setLeft(current.getLeft());
}
else{
parent.setRight(current.getLeft());
}
return current.getValue();
}
else if(current.getLeft() == null)
{
if(current == root)
root = current.getRight();
else if(isLeftChild)
parent.setLeft(current.getRight());
else
parent.setRight(current.getRight());
return current.getValue();
}
else
{
MyNodeClass<Key,Value> successor = getSuccessor(current);
if(current == root)
root = successor;
else if(isLeftChild)
parent.setLeft(successor);
else
parent.setRight(successor);
successor.setLeft(current.getLeft());
return current.getValue();
}
}
#Override
public String stringLevelOrder() {
return(LevelOrder(root));
}
private MyNodeClass<Key,Value> getSuccessor(MyNodeClass<Key,Value> deleteNode)
{
MyNodeClass<Key,Value> successorParent = deleteNode;
MyNodeClass<Key,Value> successor = deleteNode;
MyNodeClass<Key,Value> current = deleteNode.getRight();
while(current != null)
{
successorParent = successor;
successor = current;
current = current.getLeft();
}
if(successor != deleteNode.getRight())
{
successorParent.setLeft(successor.getRight());
successor.setRight(deleteNode.getRight());
}
return successor;
}
public static void main(String[] args)
{
MyBinarySearchTree<Double, MyStudent> BST = new MyBinarySearchTree<Double, MyStudent>();
MyStudent myStud1 = new MyStudent();
MyStudent myStud2 = new MyStudent();
MyStudent myStud3 = new MyStudent();
MyStudent myStud4 = new MyStudent();
MyStudent myStud5 = new MyStudent();
myStud1.init("Clarise", 1.1);
myStud2.init("Christopher", 1.2);
myStud3.init("John", 1.3);
myStud4.init("Chloe", 1.4);
myStud5.init("Goo", 1.5);
System.out.println(BST.insert(myStud1.getGPA(), myStud1));
System.out.println(BST.insert(myStud2.getGPA(), myStud2));
System.out.println(BST.insert(myStud3.getGPA(), myStud3));
System.out.println(BST.insert(myStud4.getGPA(), myStud4));
System.out.println(BST.insert(myStud5.getGPA(), myStud5));
System.out.println("Delete Key 1.0: " +BST.delete(1.3));
System.out.println("Delete Key 1.4: " +BST.delete(1.4));
System.out.println("Is Empty?: " +BST.isEmpty());
System.out.print("Find 3.9: "+ BST.find(3.9));
}
}
The result of the main is the following:
{Clarise:1.1}
{Christopher:1.2}
{John:1.3}
{Chloe:1.4}
{Goo:1.5}
Delete Key 1.0: null
Delete Key 1.4 null
Is Empty?: false
Find 3.9: null
I'm not entirely sure what the issue is and I've had some help from others, however they can't find the problem. Hoping that someone else can see something that we don't see.
In your insert method, after you've checked that root is not null, you are inserting newNode into the newNode instead of inserting it into the root.
This:
MyNodeClass<Key,Value> current = newNode;
MyNodeClass<Key,Value> parent;
Should be:
MyNodeClass<Key,Value> current = root;
MyNodeClass<Key,Value> parent;
P.S. any kind of testing would show you the problem with your insert within a minute. You could write a size() method and see that your inserts are not working, you could write a toString() method and see the state of the tree, finally you could debug.
MyNodeClass<Key,Value> current = newNode;
There is problem here.
If a tree is not empty, then your "current" should begin at root node. What you done is insert "newNode" to "newNode".
Change the code to be:
MyNodeClass<Key,Value> current = root;
I wanted to try and implement my own BST as an exercise, but I am stuck on the node removal. I cannot figure out why it doesn't work in some cases. I took the algorithm from a book, but when I test it with random elements, there are cases in which it does not remove the element, or even messes up their order so they are no longer sorted. What am I doing wrong and what would be a better way to accomplish this?
NOTE: All of the println() statements in the methods are there only for debugging purposes
class TreeNode<T extends Comparable<T>> {
T data;
TreeNode<T> left;
TreeNode<T> right;
TreeNode<T> parent;
TreeNode(T data) {
this.data = data;
}
boolean hasBothChildren() {
return hasLeftChild() && hasRightChild();
}
boolean hasChildren() {
return hasLeftChild() || hasRightChild();
}
boolean hasLeftChild() {
return left != null;
}
boolean hasRightChild() {
return right != null;
}
boolean isLeftChild() {
return this.parent.left == this;
}
boolean isRightChild() {
return this.parent.right == this;
}
}
public class BinaryTreeSet<T extends Comparable<T>> {
private TreeNode<T> root;
private void makeRoot(T element) {
TreeNode<T> node = new TreeNode<T>(element);
root = node;
}
private TreeNode<T> find(T element) {
TreeNode<T> marker = root;
TreeNode<T> found = null;
while (found == null && marker != null) {
int comparator = (marker.data.compareTo(element));
if (comparator > 0)
marker = marker.left;
else if (comparator < 0)
marker = marker.right;
else
found = marker;
}
return found;
}
private TreeNode<T> max(TreeNode<T> root) {
TreeNode<T> currentMax = root;
while (currentMax.hasRightChild()) {
currentMax = currentMax.right;
}
return currentMax;
}
// returns the inorder predecessor of node
private TreeNode<T> predecessor(TreeNode<T> node) {
return max(node.left);
}
// removes a given node with 0 or 1 children
private void removeNode(TreeNode<T> node) {
if (!node.hasChildren()) {
System.out.println("node with no children");
if (node.isLeftChild())
node.parent.left = null;
else
node.parent.right = null;
}
else {
System.out.println("node with 1 child");
if (node.isRightChild()) {
if (node.hasLeftChild())
node.parent.right = node.left;
else if (node.hasRightChild())
node.parent.right = node.right;
}
else if (node.isLeftChild()) {
if (node.hasLeftChild())
node.parent.left = node.left;
else if (node.hasRightChild())
node.parent.left = node.right;
}
}
node = null;
}
public BinaryTreeSet() {
root = null;
}
public void addElement(T element) {
if (root == null)
makeRoot(element);
else {
TreeNode<T> marker = root;
TreeNode<T> node = new TreeNode<T>(element);
boolean done = false;
while(!done) {
int comparator = marker.data.compareTo(element);
if (comparator > 0) {
if (marker.hasLeftChild())
marker = marker.left;
else {
marker.left = node;
done = true;
}
}
else if (comparator < 0) {
if (marker.hasRightChild())
marker = marker.right;
else {
marker.right = node;
done = true;
}
}
else
return;
node.parent = marker;
}
}
}
public boolean contains(T element) {
boolean found = (find(element) == null)? false : true;
return found;
}
public boolean removeElement(T element) {
TreeNode<T> node = find(element);
if (node == null)
return false;
// removal of a node with no children
if (!node.hasChildren()) {
if (node.isLeftChild()) {
node.parent.left = null;
}
else if (node.isRightChild()) {
node.parent.right = null;
}
}
// removal of a node with both children
else if (node.hasBothChildren()) {
TreeNode<T> pred = predecessor(node);
T temp = pred.data;
pred.data = node.data;
node.data = temp;
removeNode(pred);
}
// removal of a node with only 1 child
else {
if (node.isRightChild()) {
if (node.hasLeftChild())
node.parent.right = node.left;
else if (node.hasRightChild())
node.parent.right = node.right;
}
else if (node.isLeftChild()) {
if (node.hasLeftChild())
node.parent.left = node.left;
else if (node.hasRightChild())
node.parent.left = node.right;
}
}
node = null;
System.out.println("item removed: " + !contains(element));
return true;
}
}
please add following Method into BinaryTreeSet Class and call it,
which will show you current element list with Left/Right prefix.
boolean rootOncePrint = true;
public void printAllTree(TreeNode<T> startNode){
if(startNode == null) return;
//System.out.println(startNode.data);
if(rootOncePrint){
System.out.println("Root : " + startNode.data);
rootOncePrint = false;
}
if(startNode.hasChildren()){
if(startNode.hasLeftChild()){
printAllTree(startNode.left);
}
if(startNode.hasRightChild()){
printAllTree(startNode.right);
}
}
if(startNode != root){
T parentValue = startNode.parent.data;
T dataValue = startNode.data;
System.out.println(startNode.data + ((parentValue.compareTo(dataValue) > 0)?"L":"R"));
}
}
After Add this code, try to add/remove element into BinaryTreeSet so
you will get to know what's going on.
Found the bug that was causing me headaches. The problem was in the cases where I remove nodes with 0 or 1 child. I was not updating their parent nodes, so that messed up with the code. So, instead of, for example
if (node.hasLeftChild())
node.parent.right = node.left;
I should have written
if (node.hasLeftChild()) {
node.parent.left = node.left;
node.left.parent = node.parent;
}
in all cases where I deal with a single child. Also, I forgot to update the root, when the root is the target of the removeElement() function.
However, as it currently stands, I feel I have a lot of repetition in the code. I am yet to come up with a more elegant solution.
EDIT: There are other minor bugs as well, mainly in the isRightChild() and isLeftChild() functions, resulting in NullPointerException if the node in question does not have a parent.