CS 4521 Fall Semester, 2009

20 Points

**
The assignment **
consists of two parts:

(1) adding delete to your implementation of B-Tree operations (15 points),
and

(2) writing pseudocode for the binomial heap merge operation (5 points).

**Implementation of B-Tree Deletion**

For the deletion operation, I followed the strategy of the text,
using a non-recursive top-level routine
** B-Tree-Delete()**
that called a recursive routine

B-Tree-Delete(T,k) r <- root[T] if r = NIL or n[r] = 0 then print "Error: "Attempt to delete from empty tree." else B-Tree-Delete-Fullenough(r,k) if n[r] = 0 then if leaf[r] then root[T] <- NIL else root[T] <- c_1[r] deallocate r

For ** B-Tree-Delete-Fullenough()**, I followed the
pseudocode given in the lab session. But note a couple of subtleties.
First, in case 3b, there are two subcases: when c

if i = n[x] + 1 |> Then we need to merge from left, not from right then i <- i - 1 B-Tree-Merge-Children( x, i, c_i[x], c_(i+1)[x] )(rather than having two separate calls to

Second, it isn't necessary to implement full

k' <- B-Tree-Minimum( c_(i+1)[x] )and similarly, the predecessor of

Here is pseudocode for

B-Tree-Minimum(x) while not leaf[x] do x <- c_1[x] return key_1[x]

**Overall strategy for B-Tree-Delete-Fullenough()**

My overall strategy to implement ** B-Tree-Delete-Fullenough()**
was to implement and test case 1 (and "case 0") first, then
the "find the predecessor/successor" cases 2a and 2b,
then the "merge" of case 2c (also used in case 3b), then
the "borrow-left" and
"borrow-right" subcases of case 3a, and finally the "merge" of case 3b.

As I have mentioned, the "borrow-left" operation is sort of like the
"rotate" operation used in red-black trees (I think that the split-child and
merge-children operations could be mostly performed by a sequence of
"borrow" operations also, so in that sense split and merge are kinds of
"super-rotates"). The pseudocode for
** B-Tree-Borrow-Left()**
is below; the steps in

B-Tree-Borrow-Left( x, i ) y <- c_(i-1)[x] |> rename left child to simplify pseudocode z <- c_i[x] |> rename child to simplify pseudocode shift all keys (and child pointers if not leaf[z]) up one index |> in node z to make room for one more key and child pointer increment n[z] key_1[z] <- key_(i-1)[x] |> "rotate" keys key_(i-1)[x] <- key_(n[y])[y] |> c_1[z] <- c_(n[y]+1)[y] |> and move a child pointer into z decrement n[y]

**Implementation of B-Tree-Merge-Children() **

The ** B-Tree-Merge-Children()** operation is similar to

B-Tree-Merge-Children( x, i, y, z ) copy the t-1 keys of z into the top t-1 key positions of y if not leaf[y] then copy the t child pointers of z into the top t child pointer positions of y key_t[y] <- key_i[x] |> move the splitting key down to y n[y] <- 2t - 1 |> y is now a full node shift the keys from index i+1 to n[x] down one index in node x shift the child pointers from index i+2 to n[x]+1 down one index in node x decrement n[x] |> since it has lost its splitting key deallocate z

** Hints: **
In the previous assignment, near the end, there is some
**Helpful code**, and some **useful pseudocode**.

** Testing: **

Run your implementation on the test files:
** treetest3**,

Note that

** What To Hand In: **

- Clearly marked scripts of
through`treetest3`which test deletion. Outline the nodes and draw the child pointers by hand on your output.`treetest6` - Well documented code for your B-tree implementation.
- Do Exercise 19.2-1 page 471:
Write pseudocode for
called in line 2 of the`Binomial-Heap-Merge()`algorithm on page 463 of the text. This is basically a linked list merge operation, similar to the array merge operation of merge-sort.`Binomial-Heap-Union()`