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.

cha<strong>in</strong><strong>in</strong>g rule, however. In particular, if space is at a premium (for example, if we<br />

are writ<strong>in</strong>g a program for a small h<strong>and</strong>held device), then we can use the<br />

alternative approach of always stor<strong>in</strong>g each entry directly <strong>in</strong> a bucket, at most one<br />

entry per bucket. This approach saves space because no auxiliary structures are<br />

employed, but it requires a bit more complexity to deal with collisions. There are<br />

several vari ants of this approach, collectively referred to as open address<strong>in</strong>g<br />

schemes, which we discuss next. Open address<strong>in</strong>g requires that the load factor is<br />

always at most 1 <strong>and</strong> that entries are stored directly <strong>in</strong> the cells of the bucket array<br />

itself.<br />

L<strong>in</strong>ear Prob<strong>in</strong>g<br />

A simple open address<strong>in</strong>g method for collision h<strong>and</strong>l<strong>in</strong>g is l<strong>in</strong>ear prob<strong>in</strong>g. In this<br />

method, if we try to <strong>in</strong>sert an entry (k, v) <strong>in</strong>to a bucket A[i] that is already<br />

occupied, where i = h(k), then we try next at A[(i + 1) modN]. If A[(i + 1) mod N]<br />

is also occupied, then we try A[(i + 2) mod N], <strong>and</strong> so on, until we f<strong>in</strong>d an empty<br />

bucket that can accept the new entry. Once this bucket is located, we simply <strong>in</strong>sert<br />

the entry there. Of course, this collision resolution strategy requires that we<br />

change the implementation of the get(k, v) operation. In particular, to perform<br />

such a search, followed by either a replacement or <strong>in</strong>sertion, we must exam<strong>in</strong>e<br />

consecutive buck ets, start<strong>in</strong>g from A [h(k)], until we either f<strong>in</strong>d an entry with key<br />

equal to k or we f<strong>in</strong>d an empty bucket. (See Figure 9.5.) The name "l<strong>in</strong>ear<br />

prob<strong>in</strong>g" comes from the fact that access<strong>in</strong>g a cell of the bucket array can be<br />

viewed as a "probe".<br />

Figure 9.5: Insertion <strong>in</strong>to a hash table with <strong>in</strong>teger<br />

keys us<strong>in</strong>g l<strong>in</strong>ear prob<strong>in</strong>g. The hash function is h(k) = k<br />

mod 11. Values associated with keys are not shown.<br />

To implement remove(k), we might, at first, th<strong>in</strong>k we need to do a consider able<br />

amount of shift<strong>in</strong>g of entries to make it look as though the entry with key k was<br />

never <strong>in</strong>serted, which would be very complicated. A typical way to get around<br />

this difficulty is to replace a deleted entry with a special "available" marker<br />

object. With this special marker possibly occupy<strong>in</strong>g buckets <strong>in</strong> our hash table, we<br />

modify our search algorithm for remove(k) or get(k) so that the search for a<br />

534

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

Saved successfully!

Ooh no, something went wrong!