1.大体思路
每次选取数组的一段,取段尾元素为key值,遍历一遍该段,将比key值小的数放在key的前面,比key值大的数放在key的后面(升序排序);假设key的索引值为idx,则在【0, idx - 1】和【idx + 1, arr.size() - 1】之间在此调用该函数,此递归函数的结束标志是:left < right不成立。
2.代码
#include <iostream>
#include <ctime>
using namespace std;
void InitArr(int *nArr, int nLen) { //初始化数组
//srand(time(NULL));
for(int i = 0; i < nLen; ++i) {
//nArr[i] = rand() % 100;
nArr[i] = i;
}
}
void PrintArr(int *nArr, int nLen) {
for(int i = 0; i < nLen; ++i) {
cout << nArr[i] << " ";
}
cout << endl;
}
void Swape(int *p1, int *p2) {
int nTmp = *p1;
*p1 = *p2;
*p2 = nTmp;
}
void RandomSort(int *nArr, int nLen) {
srand(time(NULL));
for(int i = 0; i < nLen; ++i) {
int nIndex = rand() % nLen;
Swape(&nArr[i], &nArr[nIndex]);
//Sleep(2000); //等待2s,更新随机种子
}
}
//递增排序
int PatitionUp(int *nArr, int nLeft, int nRight) {
int nKey = nArr[nRight];
int i = nLeft - 1;
for(int j = nLeft; j < nRight; ++j) {
if(nArr[j] < nKey) { //反正不稳定,就用<代替≤,省取相等情况下多余的交换运行时间
i++;
Swape(&nArr[j], &nArr[i]); //不稳定排序的原因 eg:1 5 8 8 6 11 7
}
}
Swape(&nArr[i + 1], &nArr[nRight]); //将主元素插入到中间
return i + 1;
}
//递减排序
int PatitionDown(int *nArr, int nLeft, int nRight) {
int nKey = nArr[nRight];
int i = nLeft - 1;
for(int j = nLeft; j < nRight; ++j) {
if(nArr[j] > nKey) {
++i;
Swape(&nArr[i], &nArr[j]); //不稳定排序的原因
}
}
Swape(&nArr[i + 1], &nArr[nRight]); //将主元素插入到中间
return i + 1;
}
void QuickSort(int *nArr, int nLeft, int nRight) {
if(nLeft < nRight) {
//分解
int nTmpPos = PatitionUp(nArr, nLeft, nRight);
//解决、合并
QuickSort(nArr, nLeft, nTmpPos - 1);
QuickSort(nArr, nTmpPos + 1, nRight);
}
}
int main() {
int Arr[1000];
int Len = 20;
InitArr(Arr, Len);
// PrintArr(Arr, Len);
RandomSort(Arr, Len);
PrintArr(Arr, Len);
QuickSort(Arr, 0, Len - 1);
PrintArr(Arr, Len);
return 0;
}
3.运行结果
4.总结
时间复杂度O(nlogn),空间复杂度O(1),不稳定排序。