快速排序的原理见http://en.wikipedia.org/wiki/Quicksort
快速排序采用分而治之的策略,即partition-sort。先对待排序的序列进行partition操作,即从序列中选择一个基准值(pivot),将序列中的元素与基准值比较,排序(sort)成小于和大于基准值的两个序列;再从两个序列中分别选择新的基准值,对两个序列再进行排序;直至整个序列不能再分,完成总体的排序。
假设序列的长度为N,需进行x次partition-sort,则有2^x=N,则快速排序的时间复杂度为O(logN)。
In-place快速排序不需要额外的存储空间,其实现伪代码为:
// left is the index of the leftmost element of the array
// right is the index of the rightmost element of the array (inclusive)
// number of elements in subarray = right-left+1
function partition(array, 'left', 'right', 'pivotIndex')
'pivotValue' := array['pivotIndex']
swap array['pivotIndex'] and array['right'] // Move pivot to end
'storeIndex' := 'left'
for 'i' from 'left' to 'right' - 1 // left ≤ i < right
if array['i'] < 'pivotValue'
swap array['i'] and array['storeIndex']
'storeIndex' := 'storeIndex' + 1
swap array['storeIndex'] and array['right'] // Move pivot to its final place
return 'storeIndex'
function quicksort(array, 'left', 'right')
// If the list has 2 or more items
if 'left' < 'right'
// See "Choice of pivot" section below for possible choices
choose any 'pivotIndex' such that 'left' ≤ 'pivotIndex' ≤ 'right'
// Get lists of bigger and smaller items and final position of pivot
'pivotNewIndex' := partition(array, 'left', 'right', 'pivotIndex')
// Recursively sort elements smaller than the pivot
quicksort(array, 'left', 'pivotNewIndex' - 1)
// Recursively sort elements at least as big as the pivot
quicksort(array, 'pivotNewIndex' + 1, 'right')
下图是in-place快速排序的示意图:
In-place partition in action on a small list. The boxed element is the pivot element, blue elements are less or equal, and red elements are larger.
实现代码为:
void my_swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
int partition(int* a, int left, int right)
{
int pivotIndex = (left + right) / 2;
int pivotValue = a[pivotIndex];
my_swap(a[pivotIndex], a[right]);
int storedIndex = left;
for( int i = left; i < right; i++ )
{
if( a[i] < pivotValue )
{
my_swap( a[i], a[storedIndex] );
storedIndex ++;
}
}
my_swap( a[right], a[storedIndex] );
return storedIndex;
}
int quick_sort( int* a, int left, int right )
{
if( left < right )
{
int index = partition(a, left, right);
quick_sort(a, left, index-1);
quick_sort(a, index+1, right);
}
else
{
return 1;
}
}