|
I put it here in case you need to refresh your knowledge - as always, I added my personal touch to the material....
|
For simplicity, I will omit the external nodes and draw the binary search tree as:
|
|
Examples:
|
|
/* ===========================
Entry structure
=========================== */
public class BSTEntry
{
// ******** The "payload ***************************
public String key; // I use concrete data type again....
public Integer value;
// Links that let you traverse UP and DOWN the BST
public BSTEntry parent; // Parent node
public BSTEntry left; // Left child node
public BSTEntry right; // Right child node
}
|
public class BSTEntry
{
public String key;
public Integer value;
public BSTEntry parent;
public BSTEntry left;
public BSTEntry right;
public BSTEntry(String k, Integer v) // Constructor
{
key = k;
value = v;
parent = null;
left = null;
right = null;
}
}
|
For brevety sake, I left out the methods:
|
(I can do that because I made the variables public). It's very easy to write these methods....
|
Therefore:
|
public class BST
{
public BSTEntry root; // Reference to the root node of the BST
}
|
public class BST
{
public BSTEntry root; // Reference to the root node of the BST
// Constructor
public BST()
{
root = null;
}
}
|
|
|
/* ================================================================
findEntry(k): find entry with key k
Return: reference to (k,v) IF k is in BST
reference to parent(k,v) IF k is NOT in BST (for put)
================================================================ */
public BSTEntry findEntry(String k)
{
BSTEntry curr_node; // Current node in search
BSTEntry prev_node; // The node BEFORE the curr node
/* --------------------------------------------
Find the node with key == "k" in the BST
-------------------------------------------- */
curr_node = root; // Always start at the root node
prev_node = root; // Remember the previous node for insertion
while ( curr_node != null )
{
if ( k.compareTo( curr_node.key ) < 0 )
{
prev_node = curr_node; // Remember prev. node
curr_node = curr_node.left; // Continue search in left subtree
}
else if ( k.compareTo( curr_node.key ) > 0 )
{
prev_node = curr_node; // Remember prev. node
curr_node = curr_node.right; // Continue search in right subtree
}
else // k == current.key
{
// Found key in BST
return curr_node;
}
}
/* ======================================
When we reach here, k is NOT in BST
====================================== */
return prev_node; // Return the previous (parent) node
}
|
|
/* ================================================================
get(k): find key k and return assoc. value
================================================================ */
public Integer get(String k)
{
BSTEntry p; // Help variable
/* --------------------------------------------
Find the node with key == "key" in the BST
-------------------------------------------- */
p = findEntry(k);
if ( k.equals( p.key ) )
return p.value;
else
return null;
}
|
/* ================================================================
put(k, v): store the (k,v) pair into the BST
1. if the key "k" is found in the BST, we replace the val
that is associated with the key "k"
1. if the key "k" is NOT found in the BST, we insert
a new node containing (k, v)
================================================================ */
public void put(String k, Integer v)
{
BSTEntry p; // Help variable
/* ----------------------------------------------------------
Handle the EMPTY BST separately....
---------------------------------------------------------- */
if ( root == null )
{ // Insert into an empty BST
root = new BSTEntry( k, v );
return;
}
/* --------------------------------------------
Find the node with key == "key" in the BST
-------------------------------------------- */
p = findEntry(k);
// If found, put() is update....
if ( k.equals( p.key ) )
{
p.value = v; // Update value
return;
}
/* ------------------------------------------------
Not found: Insert a new entry (k,v) under p !!!
------------------------------------------------ */
BSTEntry q = new BSTEntry( k, v );
q.parent = p; // p is the parent
if ( k.compareTo( p.key ) < 0 )
p.left = q; // Add q as left child
else
p.right = q; // Add q as right child
}
|
if ( k not in BST )
{
return; // Nothing to delete
}
/****** The "Hibbard deletion algorithm" ******/
if ( k has no subtrees ) // x x
{ // / \ ==> /
unlink k from k's parent; // y k y
return; //
}
if ( k has 1 tree ) // x x
{ // / \ ==> / \
make k's parent point to k's subtree; // y k y z
return; // \
} z
/* k has 2 subtrees - TOUGH */
(1) find the successor of k:
go right once
go left all the way down
(2) Replace k with k's successor;
(3) Make the successor's parent point to the successor's right subtree;
|
/* =======================================================
remove(k): delete entry containg key k
======================================================= */
public void remove(String k)
{
BSTEntry p; // Help variable
BSTEntry parent; // parent node
BSTEntry succ; // successor node
/* --------------------------------------------
Find the node with key == "key" in the BST
-------------------------------------------- */
p = findEntry(k);
if ( ! k.equals( p.key ) )
return; // Not found ==> nothing to delete....
/* ========================================================
Hibbard's Algorithm
======================================================== */
if ( p.left == null && p.right == null ) // Case 0: p has no children
{
parent = p.parent;
/* --------------------------------
Delete p from p's parent
-------------------------------- */
if ( parent.left == p )
parent.left = null; // p was left child
else
parent.right = null; // p was the right child
return;
}
if ( p.left == null ) // Case 1a: p has 1 (right) subtree
{
parent = p.parent;
/* ----------------------------------------------
Link p's right child as p's parent child
---------------------------------------------- */
if ( parent.left == p )
parent.left = p.right; // p has a right subtree
else
parent.right = p.right; // p has a right subtree
return;
}
if ( p.right== null ) // Case 1b: p has 1 (left) child
{
parent = p.parent;
/* ----------------------------------------------
Link p's left child as p's parent child
---------------------------------------------- */
if ( parent.left == p )
parent.left = p.left;
else
parent.right = p.left;
return;
}
/* ================================================================
Tough case: node has 2 children - find successor of p
succ(p) is as as follows: 1 step right, all the way left
Note: succ(p) has NOT left child !
================================================================ */
// (1) Find successor(p)
succ = p.right; // Go right once step
// BTW, p has a right subtree
// because p has 2 children....
while ( succ.left != null ) // Go all the way left downwards
succ = succ.left;
/* -----------------------------------------
Now: succ = the successor of p
----------------------------------------- */
// (2) Replace k with k's successor;
p.key = succ.key; // Replace p with successor
p.value = succ.value;
// (3) Make the successor's parent point to
// successor's right subtree;
parent = succ.parent; // Prepare to delete
parent.left = succ.right; // Link right tree to parent's left
return;
}
|
How to run the program:
|
Partial output: (the BST is printed side ways)
[zebra,1600]
[tiger,8888]
[owl,2000]
[man,5000]
[lion,9999]
[jackal,4000]
[horse,2000]
[donkey,1900]
[dog,1000]
[cow,700]
[cat,500]
[ape,1500]
================================
BST after remove("lion"):
[zebra,1600]
[tiger,8888]
[owl,2000]
[man,5000]
[jackal,4000]
[horse,2000]
[donkey,1900]
[dog,1000]
[cow,700]
[cat,500]
[ape,1500]
|
|
Example:
|
|
|
Examples:
| Example 1 | Example 2 |
|---|---|
|
|
|
Examples:
| Example 1 | Example 2 |
|---|---|
|
|
|
How to find successor(x):
|
|
How to find predecessor(x):
|
|
|
|
|
|
|