快速排序详解
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; }