简体   繁体   中英

Median of 3 partitioning

I found the following code for finding a pivot for quicksort using median of first, last and middle element:

int middle = ( low + high ) / 2;
if( a[ middle ].compareTo( a[ low ] ) < 0 )
    swapReferences( a, low, middle );
if( a[ high ].compareTo( a[ low ] ) < 0 )
    swapReferences( a, low, high );
if( a[ high ].compareTo( a[ middle ] ) < 0 )
    swapReferences( a, middle, high );

// Place pivot at position high - 1
swapReferences( a, middle, high - 1 );
Comparable pivot = a[ high - 1 ];

I want to know after finding the median, why is the swap done with index high-1 instead of high?

The reason is that the algorithm does not only find the median, it also sorts the low, middle and high elements. After the three permutations you know that a[middle]<=a[high]. So you need only to partition the elements before high, because a[high] is greater or equal to pivot.

Let's look at an example: low=0, middle=4 and high=8. Your array is like this:

lowerOrEqualToPivot X X X pivot X X X greaterOrEqualToPivot

If you swap middle with high, you need to partition the 8 elements between brackets :

[ lowerOrEqualToPivot X X X greaterOrEqualToPivot X X X ] pivot

If you swap middle with high-1, you need to split only 7 elements:

[ lowerOrEqualToPivot X X X X X X ] pivot greaterOrEqualToPivot

By the way there is a bug in the first line:

int middle = ( low + high ) / 2; //Wrong
int middle = ( low + high ) >>> 1; //Correct

The reason is that if (low + high) is greater than Integer.MAX_VALUE you will have an overflow and middle will be a negative number. The second line will always give you a positive result.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM