Entry put(Key k, Value v)
{
/* -------------------------
Special case: empty tree
------------------------- */
if ( root == null )
{
root = create new root node;
root.entry[0] = (k,v);
return(null);
}
/* -----------------------------------
Find key k in the tree....
----------------------------------- */
p = keySearch(k); // keySearch: see click here
/* -----------------------------------
Handle the case when key k is found
----------------------------------- */
if ( p != null && p.key == k )
{
p.value = v;
return (old Value in p); // Done...
}
/* ------------------------------------------------
Key k not found...
Then: keySearch(k) ended at a node p with
only external children node
------------------------------------------------ */
p = Node of (2,4)-tree where keySearch(k) ended;
// This is a node with only external children node
e = new Entry(k, v); // Create entry using k and v
/* ------------------------------------------------
Invoke a recursive insert procedure
(It MUST be recursive because we may need to
REPEAT the procedure further up the tree !!!
(That is when a node overflows and splits !!!)
------------------------------------------------ */
insertEntryInThisNode(e, null (the right subtree), p);
// Parameters:
// e = the new entry that is inserted
// second parameter = the RIGHT subtree of e
// p = node used to insert e
}
|
Java code:
/* ================================================
put(k): insert (k,v)
================================================ */
Integer put(String k, Integer v)
{
Node p;
Entry e;
/* ------------------------
Special case: empty tree
------------------------ */
if ( root == null )
{
p = new Node();
p.e[0] = new Entry(k, v);
root = p;
p.parent = p; // Parent(root) == root
return(null);
}
/* ------------------------
Other cases
------------------------ */
e = keySearch(k);
// keySearch sets "searchEndPos = last node visited
/* ------------------------
key found, update value
------------------------ */
if ( e != null && k.compareTo(e.key) == 0 )
{
Integer oldValue;
System.out.print("*** Update value of " + k
+ " in entry " + e);
oldValue = e.value;
e.value = v;
return(oldValue);
}
/* ------------------------------------------
key not found:
insert (k,v) in node "searchEndPos"
------------------------------------------ */
e = new Entry(k,v);
insertEntryInThisNode(e, null, searchEndPos);
return(null);
}
|
(Pseudo code):
/* -----------------------------------------------------------
insertEntryInThisNode( e, rightSubTree, p ):
inserts: [e, e's rightSubTree] into node p
Note:
Since p contains multiple entries, we must insert e
in the correct position inside p !!!
This will require moving some elements in an array !!
------------------------------------------------------------ */
void insertEntryInThisNode(Entry e, Node rightSubTree, Node p)
{
/* =========================================
Make p the parent node of rightSubTree
========================================= */
if ( rightSubTree != null )
rightSubTree.parent = p;
/* ----------------------------------------------
Case 1: node p has space left for new entry
---------------------------------------------- */
if ( # enties in p <= 2 )
{
insert [e, rightSubTree] in the correct position inside p
return;
}
/* -------------------------------------------------------------
Case 2: node p is full:
1. split the oevrflow node
2. insert left over entry + right tree into parent node
------------------------------------------------------------- */
Sort the full node + (e, rightSubTree):
|
/* =======================================================
insertEntryInThisNode(e, rightSubTree, p):
1. insert "e" and its "rightSubTree" in node p
2. if over flow, split and insert in parent
======================================================= */
public void insertEntryInThisNode(Entry e, Node rightSubTree, Node p)
{
int i;
Node q;
Entry n;
/* =========================================
Make p the parent node of rightSubTree
========================================= */
if ( rightSubTree != null )
rightSubTree.parent = p;
if ( p.e[2] == null )
{
/* -----------------
There is space
----------------- */
insertEntryDirectlyInNode(e, rightSubTree, p);
// Find the spot for (e, rightSubTree) inside p
// We may need to move array elements !!!
}
else
{
/* -----------------------------------------------
There is no more space .... Split insert !!!
----------------------------------------------- */
|
How to run the program:
|
Sample output:
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Enter a key: a Enter a value: 1 put(a,1): == After put(a,1): 0:(a,(-),(-)) vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv cheung@home6(377)> java TestProg vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Enter a key: a Enter a value: 1 put(a,1): == After put(a,1): 0:((a,1),(-),(-)) vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Enter a key: b Enter a value: 2 put(b,2): Insert b in node ((a,1),(-),(-)) == After put(b,2): 0:((a,1),(b,2),(-)) vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Enter a key: b Enter a value: 4 put(b,4): *** Update value of b in entry (b,2) == After put(b,4): 0:((a,1),(b,4),(-)) vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Enter a key: c Enter a value: 7 put(c,7): Insert c in node ((a,1),(b,4),(-)) == After put(c,7): 0:((a,1),(b,4),(c,7)) vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv Enter a key: d 4 Enter a value: put(d,4): *** Split insert ! ---- Transitional node = a b (c) d == After put(d,4): 1:((d,4),(-),(-)) 0:((c,7),(-),(-)) 0:((a,1),(b,4),(-)) |