/* file randomizedQuickSort.h */ // code by bds, 2/00 #ifndef __RANDOMIZEDQUICKSORT__ #define __RANDOMIZEDQUICKSORT__ #include /* randomizedSelect(b, e, k) returns the k-th largest element in the range [p..e). k must be in the range [0..e-b). For example, the median of the values is randomizedSelect(b, e, (e-b)/2) and the second smallest is randomizedSelect(b, e, 1). We require that class Iterator has pointer arithmetic operations and that the unknown class pointed to by dereferencing iterators has operator <= defined. */ template // use with any pointer type typename std::iterator_traits::value_type // the return type randomizedSelect(Iterator b, Iterator e, int k) // the arg types { // The items in locations [b, (b+1) .. e) will be permuted to the extent // needed to find the k-th largest. if ((e-b) <= 1) // then zero or one elements -- and that's already sorted. return b[0]; else { Iterator q = randomizedPartition(p, e); q++; int m = q - b; // size of first segment. if (k < m) return randomizedSelect(p, q, k); else return randomizedSelect(q, e, k-m); } } template inline Iterator randomizedPartition(Iterator p, Iterator e) // We assume that e > p. { Iterator i = p + rand() % (e - p); // i is random in [p..e). std::swap(*i, *p); // regular partition i = p-1; Iterator j = e; typename std::iterator_traits::value_type x = *p; while ( true ) { do j-- ; while ( !( *j <= x ) ); do i++ ; while ( !( x <= *i ) ); //do i++ ; while ( !( x <= *i ) ); if ( i < j ) std::swap( *i, *j ); else return j; } } #endif