到目前为止, 我们已经学习到了插入排序, 冒泡排序, 选择排序(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