|
Example:
|
Note: action position
|
Example:
|
|
where:
|
Example: deleting using the to-delete node with its in-order successor
|
Note:
|
|
|
(The resulting tree is no longer an AVL tree !!)
|
| Before deleting node 32 | After deleting node 32 |
|---|---|
|
|
Notes:
|
|
Important difference:
|
|
|
|
Starting at the action position node
(= parent node of the physically delete node):
{
find the first node p that is imbalanced
}
/* -----------------------------------------------
Identify grandchild node of the unbalanced node
for the restructure operation
----------------------------------------------- */
x = p;
y = the taller Child of x;
z = the taller Child of y;
tri-node-restructure( x, y, z ); // Apply the tri-node reconf. op.
|
Example:
|
|
|
Result:
|
|
p = action position; // Starting point
while ( p != root ) // Travel all the way up the tree !!!
{
if ( p is unbalanced )
{
/* -----------------------------------------------
This the is first imbalanced node (i.e., x)
----------------------------------------------- */
x = p;
/* ---------------------------------------------------
Identify nodes y and z for the restructure operation
--------------------------------------------------- */
y = the taller Child of x;
z = the taller Child of y;
p = tri-node-restructure(x, y, z);
// NOTE: we MODIFY tri-node-restructure() to
// return the root node of the NEW subtree !!!
}
p = p.parent; // traverse twards the root
}
|
public void rebalance(BSTEntry p) // The starting point is passed as parameter !!!
{
BSTEntry x, y, z, q;
while ( p != null )
{
if ( diffHeight(p.left, p.right) > 1 )
{
x = p;
y = tallerChild( x );
z = tallerChild( y );
System.out.println("tri_node_restructure: " + x + y + z);
p = tri_node_restructure( x, y, z );
}
p = p.parent;
}
}
|
public BSTEntry tri_node_restructure( BSTEntry x, BSTEntry y, BSTEntry z)
{
.... Same old code ..... (See: click here)
return b; // We return the root of the new subtree
}
|
/* ======================================================
This is the SAME remove method as BST tree, but
with rebalance() calls inserted after a deletion
to rebalance the BST....
====================================================== */
public void remove(String k)
{
BSTEntry p, q; // Help variables
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;
else
parent.right = null;
/* --------------------------------------------
Recompute the height of all parent nodes...
-------------------------------------------- */
recompHeight( parent );
/* --------------------------------------------
Re-balance AVL tree starting at ActionPos
-------------------------------------------- */
rebalance ( parent ); // Rebalance AVL tree after delete at parent
return;
}
if ( p.left == null ) // Case 1a: p has 1 (right) child
{
parent = p.parent;
/* ----------------------------------------------
Link p's right child as p's parent child
---------------------------------------------- */
if ( parent.left == p )
parent.left = p.right;
else
parent.right = p.right;
/* --------------------------------------------
Recompute the height of all parent nodes...
-------------------------------------------- */
recompHeight( parent );
/* --------------------------------------------
Re-balance AVL tree starting at ActionPos
-------------------------------------------- */
rebalance ( parent ); // Rebalance AVL tree after delete at parent
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;
/* --------------------------------------------
Recompute the height of all parent nodes...
-------------------------------------------- */
recompHeight( parent );
/* --------------------------------------------
Re-balance AVL tree starting at ActionPos
-------------------------------------------- */
rebalance ( parent ); // Rebalance AVL tree after delete at parent
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 !
================================================================ */
succ = p.right; // p has 2 children....
while ( succ.left != null )
succ = succ.left;
p.key = succ.key; // Replace p with successor
p.value = succ.value;
/* --------------------------------
Delete succ from succ's parent
-------------------------------- */
parent = succ.parent; // Prepare for deletion
parent.left = succ.right; // Link right tree to parent's left
/* --------------------------------------------
Recompute the height of all parent nodes...
-------------------------------------------- */
recompHeight( parent );
/* --------------------------------------------
Re-balance AVL tree starting at ActionPos
-------------------------------------------- */
rebalance ( parent ); // Rebalance AVL tree after delete at parent
return;
}
|
(I made some annotations to the output...)