您的位置:首页 > 其它

快速排序详解

2016-12-01 14:59 190 查看

图解过程



对于数组s = [2, 1, 3, 0, 4, 5, 8, 7, 1]进行排序

将s[0]取出作为比较值val,则s[0]位置空出

第一步,从数组右边扫描,查询第一个比val小的, 如图1查询到s[8]

将s[8]放入上一步的空格中,则s[8]空出来,如图2

第二步,从数组左边扫描,查询第一个比val大的,如图2查询到s[2]

将s[2]放入上一步的空格中,则s[2]空出来,如图3

第三步,从数组右边扫描,查询第一个比val小的,如图3查询到s[3]

将s[3]放入上一步的空格中,则s[3]空出来,如图4

++left …

–right …

直到left >= right,结束扫描,将val放入s[left],如图5

然后数组被分为0~left - 1, left + 1 ~ n继续递归排序

最好的情况是val每一次取到中间值,则复杂度为nlog(n)

最坏的情况是val每一次取到最小值或者最大值,则复杂度为n^2

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include <iomanip>
#define INF 999999999
typedef long long LL;
using namespace std;

const int MAX = 10000;
int len, arr[MAX];

void output(int *arr, int len) {
cout << "\n------\n";
for(int i = 0; i < len; ++i) {
cout << arr[i] << ' ';
}
cout << "\n------\n";
}

void quickSort(int *arr, int st, int end) { // 升序排序
if(st >= end) return;
int left = st, right = end;
int val = arr[right]; // 从左边开始寻找合适的数去填充右边的位置
while(left < right) { // 如果每次left = right = (right + left) / 2则算法复杂度为nlog(n),如果每次left = right = st或者end则复杂度为n*n
while(left < right && arr[left] < val) ++left;
arr[right] = arr[left]; // 左边的数填充了右边的位置,则需要从右边寻找合适的数去填充这个空出的位置
while(left < right && arr[right] >= val) --right;
arr[left] = arr[right];
}
arr[left] = val; // 最终剩下一个位置用来填充val,则val左边的比val小,val右边的比val大
quickSort(arr, st, left - 1);
quickSort(arr, left + 1, end);
}

int main() {
while(cin >> len) {
for(int i = 0; i < len; ++i) {
cin >> arr[i];
}
quickSort(arr, 0, len -1);
output(arr, len);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: