23.11.2014 Views

Data Structures and Algorithms in Java[1].pdf - Fulvio Frisone

Data Structures and Algorithms in Java[1].pdf - Fulvio Frisone

Data Structures and Algorithms in Java[1].pdf - Fulvio Frisone

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

The implementation of the remove(k) operation on a dictionary D implemented<br />

with a b<strong>in</strong>ary search tree T is a bit more complex, s<strong>in</strong>ce we do not wish to create<br />

any "holes" <strong>in</strong> the tree T. We assume, <strong>in</strong> this case, that a proper b<strong>in</strong>ary tree<br />

supports the follow<strong>in</strong>g additional update operation:<br />

v's<br />

removeExternal(v): Remove an external node v <strong>and</strong> its parent, replac<strong>in</strong>g<br />

parent with v's sibl<strong>in</strong>g; an error occurs if v is not external.<br />

Given this operation, we beg<strong>in</strong> our implementation of operation remove(k) of<br />

the dictionary ADT by call<strong>in</strong>g TreeSearch(k, T.root()) on T to f<strong>in</strong>d a node<br />

of T stor<strong>in</strong>g an entry with key equal to k. If TreeSearch returns an external<br />

node, then there is no entry with key k <strong>in</strong> dictionary D, <strong>and</strong> we return null (<strong>and</strong><br />

we are done). If TreeSearch returns an <strong>in</strong>ternal node w <strong>in</strong>stead, then w stores<br />

an entry we wish to remove, <strong>and</strong> we dist<strong>in</strong>guish two cases (of <strong>in</strong>creas<strong>in</strong>g<br />

difficulty):<br />

• If one of the children of node w is an external node, say node z, we simply<br />

remove w <strong>and</strong> z from T by means of operation removeExternal(z) on T.<br />

This operation restructures T by replac<strong>in</strong>g w with the sibl<strong>in</strong>g of z, remov<strong>in</strong>g both<br />

w <strong>and</strong> z from T. (See Figure 10.4.)<br />

• If both children of node w are <strong>in</strong>ternal nodes, we cannot simply remove<br />

the node w from T, s<strong>in</strong>ce this would create a "hole" <strong>in</strong> T. Instead, we proceed as<br />

follows (see Figure 10.5):<br />

○ We f<strong>in</strong>d the first <strong>in</strong>ternal node y that follows w <strong>in</strong> an <strong>in</strong>order traversal of T.<br />

Node y is the left-most <strong>in</strong>ternal node <strong>in</strong> the right subtree of w, <strong>and</strong> is found by<br />

go<strong>in</strong>g first to the right child of w <strong>and</strong> then down T from there, follow<strong>in</strong>g left<br />

children. Also, the left child x of y is the external node that immediately<br />

follows node w <strong>in</strong> the <strong>in</strong>order traversal of T.<br />

○ We save the entry stored at w <strong>in</strong> a temporary variable t, <strong>and</strong> move the<br />

entry of y <strong>in</strong>to w. This action has the effect of remov<strong>in</strong>g the former entry<br />

stored at w.<br />

○ We remove nodes x <strong>and</strong> y from T by call<strong>in</strong>g removeExternal(x) on T.<br />

This action replaces y with x's sibl<strong>in</strong>g, <strong>and</strong> removes both x <strong>and</strong> y from T.<br />

○ We return the entry previously stored at w, which we had saved <strong>in</strong> the<br />

temporary variable t.<br />

As with search<strong>in</strong>g <strong>and</strong> <strong>in</strong>sertion, this removal algorithm traverses a path from the<br />

root to an external node, possibly mov<strong>in</strong>g an entry between two nodes of this<br />

path, <strong>and</strong> then performs a removeExternal operation at that external node.<br />

589

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!