Example:
|
Note:
|
|
Example: a 4-way tree
|
Notice that:
|
|
|
Example:
|
Example:
|
Example:
|
|
|
public class Entry
{
public String key; // Again, I use concrete data types..
public Integer value;
public Entry(String k, Integer v)
{
key = k;
value = v;
}
}
|
Correspondence of the variables:
|
|
|
public class MultiWayTree
{
/* =================================================
Variable to represent a multiway tree: root !
================================================= */
public Node root;
/* =================================================
Constructor: make an empty tree
================================================= */
public MultiWayTree()
{
root = null;
}
....
}
|
|
|
Node searchEndPos; // Use an instance variable to hold value longer
// Remember that LOCAL variables
// ONLY exists INSIDE a METHOD
keySearch(k)
{
Node curr;
curr = root;
searchEndPos = curr;
/* ============================================================
It is important to know that a node looks like this:
Node: child[0] e[0] child[1] e[1] ...
0-node: null e[0] null e[1] ...
1-node: impossible !!!
2-node: child[0] e[0] child[1] null ...
3-node: child[0] e[0] child[1] e[1] child[2] null ...
============================================================= */
while ( curr != null )
{
searchEndPos = curr; // Remember the last visited node
if ( entry[0] != null && k < entry[0].key )
{
search in child[0] subtree: curr = child[0];
}
if ( entry[0] != null && k == entry[0].key )
{
found key k: return entry[0];
}
if ( entry[0] is last entry (a 1-node) )
{
search in child[1] subtree: curr = child[1];
}
=====================================================
if ( entry[1] != null && k < entry[1].key )
{
search in child[1] subtree: curr = child[1];
}
if ( entry[1] != null && k == entry[1].key )
{
found key k: return entry[1];
}
if ( entry[1] is last entry (a 2-node) )
{
search in child[2] subtree: curr = child[2];
}
.... and so on ...
}
return null; // k not found....
}
|
/* ===============================================================
keySearch(k): find entry containing key k
Return value:
e[i] if found (e[i].key == k)
null if not found
AND: searchEndPos = node last visited in search
=============================================================== */
Node searchEndPos; // Use an instance variable to hold value longer
public Entry keySearch(String k)
{
int i;
Node curr; // current node
searchEndPos = root; // searchEndPos = previous node
// This variable is NOT local !!!
curr = root;
while ( curr != null )
{
searchEndPos = curr; // Remember the last visited node
for ( i = 0; i < d; i++ )
{
/* ============================================================
It is important to know that a node looks like this:
Node: child[0] e[0] child[1] e[1] ...
0-node: null null null null ...
1-node: impossible !!!
2-node: child[0] e[0] child[1] null ...
3-node: child[0] e[0] child[1] e[1] child[2] null ...
============================================================= */
if ( curr.e[i] != null && k.compareTo( curr.e[i].key ) < 0 )
{
curr = curr.child[i];
break; // end to for loop
}
if ( curr.e[i] != null && k.compareTo( curr.e[i].key ) == 0 )
{
return( curr.e[i] ); // found key
}
if ( i == d-1 || curr.e[i+1] == null ) // e[i] is last value key
{
curr = curr.child[i+1];
break; // end to for loop
}
}
}
return(null); // To make Java happy, it complain of no return value...
}
|
How to run the program:
|
Sample output:
2:((m,6),(-),(-))
3:((ka,6),(l,6),(-))
1:((kb,6),(-),(-))
0:((j,6),(k,6),(-))
1:((h,8),(-),(-))
2:((g,7),(-),(-))
0:((e,5),(f,6),(-))
0:((ba,6),(d,4),(i,9))
1:((ca,6),(-),(-))
1:((c,3),(-),(-))
0:((bb,6),(-),(-))
3:((b,2),(-),(-))
2:((ae,6),(af,6),(-))
0:((ab,6),(ad,6),(ax,6))
1:((ac,6),(-),(-))
0:((a,1),(aa,6),(-))
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
Enter a key: h
get(h):
((ba,6),(d,4),(i,9)) ---- traverse LEFT subtree of (i,9)
((g,7),(-),(-)) ---- traverse RIGHT subtree of (g,7)
((h,8),(-),(-)) ---- FOUND: (h,8)
== get(h) = 8
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
Enter a key: x
get(x):
((ba,6),(d,4),(i,9)) ---- traverse RIGHT subtree of (i,9)
((ka,6),(l,6),(-)) ---- traverse RIGHT subtree of (l,6)
((m,6),(-),(-)) ---- traverse RIGHT subtree of (m,6)
===== Not found... Search ended at node: ((m,6),(-),(-))
== get(x) = null
|
His loop is complex because he handle 2 things at the same time:
|
/* ===============================================================
keySearch(k): find entry containing key k
Return value:
e[i] if found (e[i].key == k)
null if not found
AND: searchEndPos = node last visited in search
=============================================================== */
Node searchEndPos; // Use an instance variable to hold value longer
public Entry keySearch(String k)
{
int i;
Node curr; // current node
int N; // Number of entries
boolean found; // Did we find the subtree already ?
searchEndPos = root; // searchEndPos = previous node
// This variable is NOT local !!!
curr = root;
while ( curr != null )
{
searchEndPos = curr; // Remember the last visited node
/* ===========================================================
Find out how many entries are stored in the current node
=========================================================== */
for ( N = 0; N < d; N++ )
if ( curr.e[N] == null )
break; // last entry found
found = false; // Flag whether we need to take the right most subtree
for ( i = 0; i < N; i++ )
{
if ( k.compareTo( curr.e[i].key ) < 0 )
{
curr = curr.child[i]; // Go to the left subtree
found = true; // We found the subtree !
// DO NOT take the right most subtree
break; // end to for loop
}
if ( k.compareTo( curr.e[i].key ) == 0 )
{
return( curr.e[i] ); // found key
}
}
if ( !found )
curr = curr.child[N]; // Go to the right-most subtree
// because no left tree was found
}
return(null); // To make Java happy, it complain of no return value...
}
|
How to run the program:
|