removeGreaterThanOrEqual
is obtained by combining the code for
getGreaterThanOrEqual, which finds
the element that is to be deleted,
with the portion of the code of
remove, which deletes an element once we know which
node
it is in.
The resulting code is given below.
public class ExtendedDBinarySearchTree extends DBinarySearchTreeWithGE
{
/** @return and delete/remove element with smallest key >= theKey
* @return null if no element has key >= theKey */
public Object removeGreaterThanOrEqual(Object theKey)
{
// first find the element to delete
BinaryTreeNode q = root, // search pointer
pq = null, // parent of q
p = null, // pointer to node with smallest
// key >= theKey found so far
pp = null; // parent of p
// search the tree
while (q != null)
{
// is q a candidate?
if (((Data) q.element).key.compareTo(theKey) >= 0)
{// yes, q is a candidate
p = q; // q is a better candidate than old p
pp = pq;
// smaller keys (better candidates) in left subtree only
pq = q;
q = q.leftChild;
}
else
{// no, q.key too small, try right subtree
pq = q;
q = q.rightChild;}
}
if (p == null)
// no element has key >= theKey
return null;
// save smallest element with key >= k
Object theElement = ((Data) p.element).element;
// proceed to delete this element from the tree
// handle case when p has two children
if (p.leftChild != null && p.rightChild != null)
{// two children
// convert to zero or one child case
// find element with largest key in left subtree of p
BinaryTreeNode s = p.leftChild,
ps = p; // parent of s
while (s.rightChild != null)
{// move to larger element
ps = s;
s = s.rightChild;
}
// move largest element from s to p
p.element = s.element;
p = s;
pp = ps;
}
// p has at most one child, save this child in c
BinaryTreeNode c;
if (p.leftChild == null)
c = p.rightChild;
else
c = p.leftChild;
// remove node p
if (p == root) root = c;
else
{// is p left or right child of pp?
if (p == pp.leftChild)
pp.leftChild = c;
else
pp.rightChild = c;
}
return theElement;
}
}
removeGreaterThanOrEqual,
we can combine the the invocations of
getGreaterThanOrEqual
and
remove
made in Program 15.12 into a single step.
The modifed version of bestFitPack
is given below.
Changes from the original are shown in red.
A test program, input, and output are given in the files
BestFit2.*.
public class BestFit2
{
// top-level nested class
public static class BinNode
{
// data members
int id, // bin identifier
unusedCapacity;
// constructor
public BinNode(int theId, int theCapacity)
{
id = theId;
unusedCapacity = theCapacity;
}
}
/** output best fit packing into bins of size binCapacity
* @param objectSize[1:objectSize.length-1] are the object sizes */
public static void bestFitPack(int [] objectSize, int binCapacity)
{
int n = objectSize.length - 1; // number of objects
int binsUsed = 0;
ExtendedDBinarySearchTree theTree; // tree of bin capacities
theTree = new ExtendedDBinarySearchTree();
// pack objects one by one
for (int i = 1; i <= n; i++)
{// pack object i
// find best bin
BinNode bestBin = (BinNode) theTree.removeGreaterThanOrEqual
(new Integer(objectSize[i]));
if (bestBin == null)
// no bin large enough, start a new bin
bestBin = new BinNode(++binsUsed, binCapacity);
System.out.println("Pack object " + i + " in bin " + bestBin.id);
// update unused capacity and put bin
// in tree unless unused capacity is zero
bestBin.unusedCapacity -= objectSize[i];
if (bestBin.unusedCapacity > 0)
theTree.put(new Integer(bestBin.unusedCapacity), bestBin);
}
}
}
remove which
searched for the element that is to be deleted.