双指针思想
无需开辟额外的空间
有两个指针i,j,分别在最左端和最右端
然后i,j两个指针往中间走
i往中间走,直到遇到第一个大于x的数,然后停下来(因为大于x的要放在右半边)【遇到小于x的数i就继续往下走】
j往中间走,直到遇到第一个小于x的数,然后停下来(小于x的数放在左半边)
此时将i所指的数与j指的数交换一下,那么i指的新的数就是小于x的数,j指的新的数就是大于x的数,归位了。
接着重复这个过程,i,j往中间走;
直到i,j相遇,就可以把区间一分为二【左边小于x,右边大于x】
会发现,任何时刻i左边的数都是小于x的,j右边的数都是大于x的
当两个指针相遇或是穿过之后,这两个指针左边的数就是大于等于x,右边的数就是大于等于x,完美的分成两个区间
【x 归位一次,就分好一次区间,不断递归左右两个区间,直到所有的x归位】
快排模板
c++版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| #include <bits/stdc++.h> using namespace std;
const int N = 1e6 + 10; int n; int q[N]; void quick_sort(int q[], int l, int r) { if (l >= r) return ; int x = q[l], i = l - 1, j = r + 1; while (i < j) { do ++i; while (q[i] < x); do --j; while (q[j] > x); if (i < j) swap(q[i], q[j]); } quick_sort(q, l, j); quick_sort(q, j + 1, r); } int main () { scanf ("%d",&n); for (int i = 0; i < n; ++i) { scanf ("%d",&q[i]); } quick_sort(q, 0, n - 1); for (int i = 0; i < n; ++i) printf ("%d ",q[i]); printf ("\n"); return 0; }
|
java版本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public static void quickSort(int[] arr,int l ,int r){ if(l >= r) return; int i = l - 1; int j = r + 1; int x = arr[l + ((r - l) >> 1)]; while(i < j){ do{ i++; }while(arr[i] < x); do{ j--; }while(arr[j] > x); if(i < j){ int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } } quickSort(arr,l,j); quickSort(arr,j+1,r); }
|