到目前为止, 我们已经学习到了插入排序, 冒泡排序, 选择排序(selection)。 这些排序算法都是comparision based sorting algorithms(即涉及到元素大小的比较来决定元素的先后顺序)。 而且算法的时间复杂度上均为O(n^2)。但是comparision based 的排序算法远非这几个算法。 而且可以通过利用其它的一些手段(例如divide and conquer technique, 分治法)实现对基于比较的排序算法的时间复杂度降低到O(nlogn)。 其中一个就是quick sort, 故名思议, quick sort 的速度很快。
quick sort 可以采用一个in-place partition algorithm实现。quck sort 在递归的时候仅需要占用stack额外空间为O(logn)。
quick sort 是一个divide and conquer algorithms。 快排序通过首先对一个large array 分成2个小的subarrays: 即the low elements and the high elements。 Quick sort 可以recursively sort the subarrays。
快排序的步骤如下:
既然需要递归, 所以我们需要知道递归的base case。
递归的base case 是地方数组的size 为0 或者为1的的时候, 此时该子数组已经是排好序的了(sorted)。
quick sort的pseudo code 如下(对数组中i 到k(inclusive)的元素进行排序):
quicksort(A, i, k): if i < k: p := partition(A, i, k) quicksort(A, i, p - 1) quicksort(A, p + 1, k)
要对这个array 进行快排序, 仅需要调用 quicksort(A, 0, length(A)-1), partition operation的伪代码如下:
// left is the index of the leftmost element of the subarray
// right is the index of the rightmost element of the subarray (inclusive)
// number of elements in subarray = right-left+1
partition(array, left, right)
pivotIndex := choose-pivot(array, left, right)// 我们可以选择正中间的元素作为pivot, 然后将其换到最左边去
pivotValue := array[pivotIndex]
swap array[pivotIndex] and array[right]
storeIndex := left
for i from left to right - 1
if array[i] ≤ pivotValue
swap array[i] and array[storeIndex]
storeIndex := storeIndex + 1
swap array[storeIndex] and array[right] // Move pivot to its final(actual) place
return storeIndex
下面以一个数组例子给上述的partition 的伪代码进行分析(下图选择最左边的作为pivot):
//quick sort for array based list #include <iostream> #include <ctime> #include <cstdlib> // 产生随机数 #include <iomanip> using namespace std; template <class elemType> void print(elemType list[], int length); template <class elemType> int partition(elemType[], int, int); template <class elemType> void swap(elemType[], int, int); template <class elemType> void recursionQuick(elemType[], int, int); //quick sort template <class elemType> void quickSort(elemType [], int); int main() { int intList[100]; int num; for (int i = 0; i < 100; i++){ num = (rand() + time(0)) %1000; intList[i] = num; } cout << "intList before sorting: " << endl; print(intList, 100); cout << endl << endl; quickSort(intList, 100); cout << "intList after quick sort: " << endl; print(intList, 100); cout << endl; system("Pause"); return 0; } template <class elemType> void print(elemType list[], int length) { int count = 0; for(int i = 0; i < length; i++) { cout << setw(5) << list[i]; count++; if(count % 10 == 0) cout << endl; } } template <class elemType> int partition(elemType list[], int left, int right) { elemType pivot; int storeIndex = left; int pivotIndex; pivotIndex= (left + right) / 2; pivot = list[pivotIndex]; swap(list, pivotIndex, right); storeIndex = left; for (int index = left; index <= right - 1; index++) if (list[index] <= pivot) { swap(list, storeIndex, index); storeIndex++; } swap(list, right, storeIndex); return storeIndex; } template <class elemType> void swap(elemType list[], int first, int second) { elemType temp; temp = list[first]; list[first] = list[second]; list[second] = temp; } template <class elemType> void recursionQuick(elemType list[], int first, int last) { int pivotLocation; if (first < last) { pivotLocation = partition(list, first, last); recursionQuick(list, first, pivotLocation - 1); recursionQuick(list, pivotLocation + 1, last); } } template <class elemType> void quickSort(elemType list[], int length) { recursionQuick(list, 0, length -1); }
运行结果如下:
参考资料: (1)Joseph Tomlin的C++ tutorial
(2)wikipedia
C++: quick sort(快排序),布布扣,bubuko.com
原文:http://blog.csdn.net/a130737/article/details/37648705