There is BinarySearchTree class. When removing a node from a BST, we can replace it with
either its predecessor or its successor. Complete the predecessor() method
so that it returns the node that comes immediately before e. Hint: the work needed to find the
predecessor is a mirror image of what is required to find a node\'s
successor, so use successor() as a resource.
BinarySearchTree class:
Solution
import java.util.AbstractSet;
import java.util.Iterator;
public class BinarySearchTree> extends AbstractSet {
protected BTNode root;
protected int size;
/**
* Initializes this BinarySearchTree object to be empty, to contain only
* elements of type E, to be ordered by the Comparable interface, and to
* contain no duplicate elements.
*/
public BinarySearchTree() {
root = null;
size = 0;
}
/**
* Initializes this BinarySearchTree object to contain a shallow copy of a
* specified BinarySearchTree object. The worstTime(n) is O(n), where n is the
* number of elements in the specified BinarySearchTree object.
*
* @param otherTree - the specified BinarySearchTree object that this
* BinarySearchTree object will be assigned a shallow copy of.
*/
public BinarySearchTree(BinarySearchTree otherTree) {
root = copy(otherTree.root, null);
size = otherTree.size;
}
protected BTNode copy(BTNode p, BTNode parent) {
if (p != null) {
BTNode q = new BTNode(p.element, parent);
q.left = copy(p.left, q);
q.right = copy(p.right, q);
return q;
}
return null;
} // method copy
/**
* Finds the predecessor of a specified BTNode object in this BinarySearchTree. The
worstTime(n) is O(n) and
* averageTime(n) is constant.
*
* @param e - the BTNode object whose successor is to be found.
* @return the successor of e, if e has a successor; otherwise, return null.
*/
protected BTNode predecessor(BTNode e) {
if (e == null) {
return null;
} else if (e.left != null) {
// successor is leftmost BTNode in right subtree of e
BTNode p = e.left;
while (p.right != null) {
p = p.right;
}
return p;
} // e has a right child
else {
// go up the tree to the right as far as possible, then go up
// to the left.
BTNode p = e.parent;
BTNode ch = e;
while ((p != null) && (ch == p.left)) {
ch = p;
p = p.parent;
} // while
return p;
} // e has no left child
// method successor
}
@SuppressWarnings(\"unchecked\")
@Override
public boolean equals(Object obj) {
if (!(obj instanceof BinarySearchTree)) {
return false;
}
return equals(root, ((BinarySearchTree) obj).root);
} // method 1-parameter equals
public boolean equals(BTNode p, BTNode q) {
if ((p == null) || (q == null)) {
return p == q;
}
if (!p.element.equals(q.element)) {
return false;
}
if (equals(p.left, q.left) && equals(p.right, q.right)) {
return true;
}
return false;
}
/**
* Returns the size of this BinarySearchTree object.
*
* @return the size of this BinarySearchTree object.
*/
@Override
public int size() {
return size;
}
/**
* Iterator method will be implemented for a future
*
* @return an iterator positioned at the smallest element in this
* Bina.
There is BinarySearchTree class. When removing a node from a BST, we.pdf
1. There is BinarySearchTree class. When removing a node from a BST, we can replace it with
either its predecessor or its successor. Complete the predecessor() method
so that it returns the node that comes immediately before e. Hint: the work needed to find the
predecessor is a mirror image of what is required to find a node's
successor, so use successor() as a resource.
BinarySearchTree class:
Solution
import java.util.AbstractSet;
import java.util.Iterator;
public class BinarySearchTree> extends AbstractSet {
protected BTNode root;
protected int size;
/**
* Initializes this BinarySearchTree object to be empty, to contain only
* elements of type E, to be ordered by the Comparable interface, and to
* contain no duplicate elements.
*/
public BinarySearchTree() {
root = null;
size = 0;
}
/**
* Initializes this BinarySearchTree object to contain a shallow copy of a
* specified BinarySearchTree object. The worstTime(n) is O(n), where n is the
* number of elements in the specified BinarySearchTree object.
*
* @param otherTree - the specified BinarySearchTree object that this
* BinarySearchTree object will be assigned a shallow copy of.
*/
public BinarySearchTree(BinarySearchTree otherTree) {
root = copy(otherTree.root, null);
size = otherTree.size;
}
2. protected BTNode copy(BTNode p, BTNode parent) {
if (p != null) {
BTNode q = new BTNode(p.element, parent);
q.left = copy(p.left, q);
q.right = copy(p.right, q);
return q;
}
return null;
} // method copy
/**
* Finds the predecessor of a specified BTNode object in this BinarySearchTree. The
worstTime(n) is O(n) and
* averageTime(n) is constant.
*
* @param e - the BTNode object whose successor is to be found.
* @return the successor of e, if e has a successor; otherwise, return null.
*/
protected BTNode predecessor(BTNode e) {
if (e == null) {
return null;
} else if (e.left != null) {
// successor is leftmost BTNode in right subtree of e
BTNode p = e.left;
while (p.right != null) {
p = p.right;
}
return p;
} // e has a right child
else {
// go up the tree to the right as far as possible, then go up
// to the left.
BTNode p = e.parent;
BTNode ch = e;
while ((p != null) && (ch == p.left)) {
ch = p;
p = p.parent;
3. } // while
return p;
} // e has no left child
// method successor
}
@SuppressWarnings("unchecked")
@Override
public boolean equals(Object obj) {
if (!(obj instanceof BinarySearchTree)) {
return false;
}
return equals(root, ((BinarySearchTree) obj).root);
} // method 1-parameter equals
public boolean equals(BTNode p, BTNode q) {
if ((p == null) || (q == null)) {
return p == q;
}
if (!p.element.equals(q.element)) {
return false;
}
if (equals(p.left, q.left) && equals(p.right, q.right)) {
return true;
}
return false;
}
/**
* Returns the size of this BinarySearchTree object.
*
* @return the size of this BinarySearchTree object.
*/
@Override
public int size() {
return size;
}
/**
* Iterator method will be implemented for a future
4. *
* @return an iterator positioned at the smallest element in this
* BinarySearchTree object.
*/
@Override
public Iterator iterator() {
// Skipped in preparation for next week
throw new UnsupportedOperationException("Not implemented yet!");
}
/**
* Determines if there is at least one element in this BinarySearchTree object
* that equals a specified element. The worstTime(n) is O(n) and
* averageTime(n) is O(log n).
*
* @param obj - the element sought in this BinarySearchTree object.
* @return true - if there is an element in this BinarySearchTree object that
* equals obj; otherwise, return false.
* @throws ClassCastException - if obj cannot be compared to the elements in
* this BinarySearchTree object.
* @throws NullPointerException - if obj is null.
*/
@Override
public boolean contains(Object obj) {
return getBTNode(obj) != null;
}
/**
* Ensures that this BinarySearchTree object contains a specified element. The
* worstTime(n) is O(n) and averageTime(n) is O(log n).
*
* @param element - the element whose presence is ensured in this
* BinarySearchTree object.
* @return true - if this BinarySearchTree object changed as a result of this
* method call (that is, if element was actually inserted); otherwise,
* return false.
* @throws ClassCastException - if element cannot be compared to the elements
* already in this BinarySearchTree object.
5. * @throws NullPointerException - if element is null.
*/
@Override
public boolean add(E element) {
if (root == null) {
if (element == null) {
throw new NullPointerException();
}
root = new BTNode(element, null);
size++ ;
return true;
}
else {
BTNode temp = root;
int comp;
while (true) {
comp = element.compareTo(temp.element);
if (comp == 0) {
return false;
}
if (comp < 0) {
if (temp.left != null) {
temp = temp.left;
} else {
temp.left = new BTNode(element, temp);
size++ ;
return true;
} // temp.left == null
} else if (temp.right != null) {
temp = temp.right;
} else {
temp.right = new BTNode(element, temp);
size++ ;
return true;
} // temp.right == null
} // while
6. } // root not null
} // method add
/**
* Ensures that this BinarySearchTree object does not contain a specified
* element. The worstTime(n) is O(n) and averageTime(n) is O(log n).
*
* @param obj - the object whose absence is ensured in this BinarySearchTree
* object.
* @return true - if this BinarySearchTree object changed as a result of this
* method call (that is, if obj was actually removed); otherwise,
* return false.
* @throws ClassCastException - if obj cannot be compared to the elements
* already in this BinarySearchTree object.
* @throws NullPointerException - if obj is null.
*/
@Override
public boolean remove(Object obj) {
BTNode e = getBTNode(obj);
if (e == null) {
return false;
}
deleteBTNode(e);
return true;
}
/**
* Finds the BTNode object that houses a specified element, if there is such an BTNode. The
worstTime(n) is O(n), and
* averageTime(n) is O(log n).
*
* @param obj - the element whose BTNode is sought.
* @return the BTNode object that houses obj - if there is such an BTNode; otherwise, return
null.
* @throws ClassCastException - if obj is not comparable to the elements already in this
BinarySearchTree object.
* @throws NullPointerException - if obj is null.
*/
7. @SuppressWarnings("unchecked")
protected BTNode getBTNode(Object obj) {
int comp;
if (obj == null) {
throw new NullPointerException();
}
if (!(obj instanceof Comparable)) {
return null;
}
Comparable compObj = (Comparable) obj;
BTNode e = root;
while (e != null) {
comp = compObj.compareTo(e.element);
if (comp == 0) {
return e;
} else if (comp < 0) {
e = e.left;
} else {
e = e.right;
}
} // while
return null;
}
/**
* Deletes the element in a specified BTNode object from this BinarySearchTree.
*
* @param p - the BTNode object whose element is to be deleted from this BinarySearchTree
object.
* @return the BTNode object that was actually deleted from this BinarySearchTree object.
*/
protected BTNode deleteBTNode(BTNode p) {
size-- ;
// If p has two children, replace p's element with p's successor's
// element, then make p reference that successor.
if ((p.left != null) && (p.right != null)) {
BTNode s = successor(p);
8. p.element = s.element;
p = s;
} // p had two children
// At this point, p has either no children or one child.
BTNode replacement;
if (p.left != null) {
replacement = p.left;
} else {
replacement = p.right;
}
// If p has at least one child, link replacement to p.parent.
if (replacement != null) {
replacement.parent = p.parent;
if (p.parent == null) {
root = replacement;
} else if (p == p.parent.left) {
p.parent.left = replacement;
} else {
p.parent.right = replacement;
}
} // p has at least one child
else if (p.parent == null) {
root = null;
} else {
if (p == p.parent.left) {
p.parent.left = null;
} else {
p.parent.right = null;
}
} // p has a parent but no children
return p;
} // method deleteBTNode
/**
* Finds the successor of a specified BTNode object in this BinarySearchTree. The
worstTime(n) is O(n) and
* averageTime(n) is constant.
9. *
* @param e - the BTNode object whose successor is to be found.
* @return the successor of e, if e has a successor; otherwise, return null.
*/
protected BTNode successor(BTNode e) {
if (e == null) {
return null;
} else if (e.right != null) {
// successor is leftmost BTNode in right subtree of e
BTNode p = e.right;
while (p.left != null) {
p = p.left;
}
return p;
} // e has a right child
else {
// go up the tree to the left as far as possible, then go up
// to the right.
BTNode p = e.parent;
BTNode ch = e;
while ((p != null) && (ch == p.right)) {
ch = p;
p = p.parent;
} // while
return p;
} // e has no right child
} // method successor
protected static class BTNode {
protected E element;
protected BTNode left = null, right = null, parent;
/**
* Initializes this BTNode object. This default constructor is defined for the sake of subclasses
of the
* BinarySearchTree class.
*/
public BTNode() {}
10. /**
* Initializes this BTNode object from element and parent.
*/
public BTNode(E element, BTNode parent) {
this.element = element;
this.parent = parent;
} // constructor
} // class BTNode
} // class BinarySearchTree