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),(-)) |