
这篇博客将介绍C++实现的递归快速排序算法。
如图所示,递归快排的思想是如下。从待排序数列中,选取一个值,作为进一步排序的中间点。这个值是序列中的任意一个元素。
接下来,看中间点左边的所有数,是否都是小于这个中间点元素的,如果是就跳过,如果不是就挪到中间点右边去。
然后看中间点右边所有数,是否都是大于这个中间点元素的,如果是就跳过,如果不是就挪到中间点左边去。
此时本次递归任务完成。
分别对中间点左边的数列和中间点右边的数列进行同样方法的排序。
以上便是快排的简单思想。实现起来有一下几点需要注意:
在将中间值选定为最左值编程时,思想有所不同。每次递归都要选定最左值作为将来的中间值,然后有两个指针,一个从左向右扫描,一个从右向左扫描。直到两个指针相遇为止。在这种思想下,要首先保证每次计算之前,数列的最右边的那个值是最大值。否则一旦最大值在最左边,并且选定为中间值,左指针向右扫描的时候将会出现无法停止的情况。右指针则不会出现这种情况,因为右指针扫描条件是元素大于中间值,停不下来的情况下必定是所有值都大于最左值,那么遇到中间值本身一定会停下来。这一点结合后面的代码将会更清晰。
另外就是每次递归时,参与排序的元素是不包括那个右边最大值的,最大值是左指针扫描的终点,避免重复。
这种快排的平均时间复杂度是nlog(n)。计算方法涉及数学归纳法在此不详述。可以参考《数据结构、算法与应用C++语言描述原书第2版》
以下附可运行单文件C++代码:
#include <iterator>
#include <iostream>
#include <algorithm> // has copy
using namespace std;
template<class T>
int indexOfMax(T a[], int n)
{// Locate the largest element in a[0:n-1].
int indexOfMax = 0;
for (int i = 1; i < n; i++)
if (a[indexOfMax] < a[i])
indexOfMax = i;
return indexOfMax;
}
template <class T>
void quickSort(T a[], int leftEnd, int rightEnd)
{
if (leftEnd >= rightEnd) return;
int leftCursor = leftEnd;
int rightCursor = rightEnd + 1;
T pivot = a[leftEnd];
while(true)
{
do{
leftCursor ++;
}while(a[leftCursor] < pivot);
do{
rightCursor --;
}while(a[rightCursor] > pivot);
if (leftCursor >= rightCursor) break;
swap(a[leftCursor], a[rightCursor]);
}
// place pivot
a[leftEnd] = a[rightCursor];
a[rightCursor] = pivot;
quickSort(a, leftEnd, rightCursor - 1);
quickSort(a, rightCursor + 1, rightEnd);
}
template <class T>
void quickSort(T a[], int n)
{
if (n <= 1) return;
int maxCursor;
maxCursor = indexOfMax(a, n);
swap(a[maxCursor], a[n-1]);
quickSort(a, 0, n-2);
}
int main() {
cout << "this is a quick sort application" << endl; // prints !!!Hello World!!!
int a[10] = {10,7,8,9,4, 2, 3, 6, 5,1};
// output the elements
cout << "a[0:9] = ";
copy(a, a+10, ostream_iterator<int>(cout, " "));
cout << endl;
// sort
quickSort(a,10);
// output the sorted sequence
cout << "After the sort, a[0:9] = ";
copy(a, a+10, ostream_iterator<int>(cout, " "));
cout << endl;
return 0;
return 0;
}
本文详细介绍了如何使用C++实现递归快速排序算法。通过选取数列中的一个值作为中间点,将数列分为两部分,分别对左右两部分进行相同操作,直至排序完成。注意在实现过程中,应确保最右值为最大值,避免左指针扫描时无法停止的问题。递归快速排序的时间复杂度平均为nlog(n)。
1113

被折叠的 条评论
为什么被折叠?



