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...)