25.11.2014 Views

Algorithms and Data Structures

Algorithms and Data Structures

Algorithms and Data Structures

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

N.Wirth. <strong>Algorithms</strong> <strong>and</strong> <strong>Data</strong> <strong>Structures</strong>. Oberon version 64<br />

Analysis of Heapsort. At first sight it is not evident that this method of sorting provides good results.<br />

After all, the large items are first sifted to the left before finally being deposited at the far right. Indeed, the<br />

procedure is not recommended for small numbers of items, such as shown in the example. However, for<br />

large n, Heapsort is very efficient, <strong>and</strong> the larger n is, the better it becomes — even compared to Shellsort.<br />

In the worst case, there are n/2 sift steps necessary, sifting items through log(n/2), log(n/2+1), ... ,<br />

log(n-1) positions, where the logarithm (to the base 2) is truncated to the next lower integer.<br />

Subsequently, the sorting phase takes n-1 sifts, with at most log(n-1), log(n-2), ..., 1 moves. In<br />

addition, there are n-1 moves for stashing the item from the top away at the right. This argument shows<br />

that Heapsort takes of the order of n × log(n) moves even in the worst possible case. This excellent<br />

worst-case performance is one of the strongest qualities of Heapsort.<br />

It is not at all clear in which case the worst (or the best) performance can be expected. But generally<br />

Heapsort seems to like initial sequences in which the items are more or less sorted in the inverse order, <strong>and</strong><br />

therefore it displays an unnatural behavior. The heap creation phase requires zero moves if the inverse<br />

order is present. The average number of moves is approximately n/2 × log(n), <strong>and</strong> the deviations from this<br />

value are relatively small.<br />

2.3.3 Partition Sort<br />

After having discussed two advanced sorting methods based on the principles of insertion <strong>and</strong> selection,<br />

we introduce a third improved method based on the principle of exchange. In view of the fact that<br />

Bubblesort was on the average the least effective of the three straight sorting algorithms, a relatively<br />

significant improvement factor should be expected. Still, it comes as a surprise that the improvement based<br />

on exchanges to be discussed subsequently yields the best sorting method on arrays known so far. Its<br />

performance is so spectacular that its inventor, C.A.R. Hoare, called it Quicksort [2.5 <strong>and</strong> 2.6].<br />

Quicksort is based on the recognition that exchanges should preferably be performed over large<br />

distances in order to be most effective. Assume that n items are given in reverse order of their keys. It is<br />

possible to sort them by performing only n/2 exchanges, first taking the leftmost <strong>and</strong> the rightmost <strong>and</strong><br />

gradually progressing inward from both sides. Naturally, this is possible only if we know that their order is<br />

exactly inverse. But something might still be learned from this example.<br />

Let us try the following algorithm: Pick any item at r<strong>and</strong>om (<strong>and</strong> call it x); scan the array from the left<br />

until an item a i > x is found <strong>and</strong> then scan from the right until an item a j < x is found. Now exchange the<br />

two items <strong>and</strong> continue this scan <strong>and</strong> swap process until the two scans meet somewhere in the middle of<br />

the array. The result is that the array is now partitioned into a left part with keys less than (or equal to) x,<br />

<strong>and</strong> a right part with keys greater than (or equal to) x. This partitioning process is now formulated in the<br />

form of a procedure. Note that the relations > <strong>and</strong> < have been replaced by ≥ <strong>and</strong> ≤, whose negations in<br />

the while clause are < <strong>and</strong> >. With this change x acts as a sentinel for both scans.<br />

PROCEDURE partition;<br />

VAR i, j: INTEGER; w, x: Item;<br />

BEGIN<br />

i := 0; j := n-1;<br />

select an item x at r<strong>and</strong>om;<br />

REPEAT<br />

WHILE a[i] < x DO i := i+1 END;<br />

WHILE x < a[j] DO j := j-1 END;<br />

IF i j<br />

END partition

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

Saved successfully!

Ooh no, something went wrong!