A problem from CLRS ,3ed.
12.3-5
Suppose that instead of each node x keeping the attribute x.p, pointing to x’s parent, it keeps x.succ, pointing to x’s successor. Give pseudocode for SEARCH,INSERT, and DELETE on a binary search tree T using this representation. These procedures should operate in time O(h), where h is the height of the tree T . (Hint:You may wish to implement a subroutine that returns the parent of a node.)
I know how to implement a subroutine that returns the parent of a node in O(h) time.
To find the parent of node x
, we should find the maximum key M
in the subtree rooted at x
first. Then, we go downward to the right from M.succ.left
. When we reach x
, the node we encounter before x
is x
's parent.
See the code.
typedef struct TREE{
struct TREE* left,right,succ;
}*BST;
PARENT(BST x)
{
if(x==root) return NULL;
BST max=TREE_MAXIMUM(x);
BST parent=max->succ,t;
if(parent) t=parent->left;
else t=root;
while(t!=x){parent=t;t=t->right;}
return parent;
}
When DELETE
x
, the succ of x
's predecessor should be modified to point to x.succ
, no longer x
. So now comes the problem--how to find the predecessor of x
in O(h) time?
When the left subtree of x
is nonempty, it's the rightmost node in x
's left subtree. However, when the left subtree of x
is empty, the predecessor is x
's ancestor, to find which calls O(h) times of PARENT
. Does that needs O(h*h) time? Or should we search downward from the root?
Notice that the operation INSERT
, also needs to find a node's predecessor.
There comes a question--what if all the keys share the same value? Then we cannot find x
's predecessor using comparison, for the key a
, which equals to key x
, may appears in x
's left subtree or right subtree.