快速排序
## 思路:
- 确定分界点:q[l] , q[(1 + r)/2] , q[r] , 随机
- 调整区间的范围:使得在
分界点左侧是数都<= x
,分界点右侧的数都>= x
(重点处理
)- 递归处理左右俩段
方法1:暴力方法实现思路
- 创建俩个数组
a[ ] , b[ ]
- 遍历
q[l ~ r]
, 如果当前的q[i] <= x
,就插入到数组 a[ ] 中,如果当前的q[i] >= x
, 就插入到数组b[]中。- 将a[ ]中的数放到q[ ]中,然后将b[ ]中的数放到q[ ]中,此时q[ ]当中的数就是有序的。
特点:
- 需要用到俩个额外空间a[ ] , b[ ]
- 时间复杂度仍然是O(n)
方法2:双指针实现思路
- 俩个指针
i , j
一个指向左边,另一个指向右边,俩个指针同时往中间走
- 只要
i < x
,此时 i 往右
移动一位,直到碰到i >= x
,此时i 停止移动
,开始移动 j ,只要j > x
, j 就往左
移动一位, 直到j <= x
,此时 j 停止移动。交换
i 和 j 的值后,指针都向中间移动一位
。- 直到 i 和 j
相遇或穿过为止
。此时 i 左边的数都 <= x , j 右边的数都 >= x。- 将左边的数和右边的数,分别继续递归,重复上述步骤。
举例
题目
给定你一个长度为 n 的整数数列。
请你使用快速排序对这个数列按照从小到大进行排序。
并将排好序的数列按顺序输出。
<br/>
输入格式
输入共两行,第一行包含整数 n。
第二行包含 n 个整数(所有整数均在 1∼109 范围内),表示整个数列。
<br/>
输出格式
输出共一行,包含 n 个整数,表示排好序的数列。
<br/>
数据范围
1 ≤ n ≤ 100000
<br/>
输入样例:5 3 1 2 4 5
输出样例:
1 2 3 4 5
代码
#include <iostream> 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 + r) / 2], i = l -1 ,j = r + 1; //设置分界点 while (i < j) //循环遍历,当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() { int i; scanf("%d", &n); for (i = 0; i < n; i ++) scanf("%d", &q[i]); quick_sort(q, 0, n - 1); for (i = 0; i < n; i ++) printf("%d ", q[i]); return 0; }
中间除了使用do while,还可以使用while循环
void quick_sort(int array[], int low, int high) { int i = low; int j = high; if(i >= j) { return; } int temp = array[low]; while(i <= j) { while(array[j] >= temp && i < j) { j--; } while(array[i] <= temp && i < j) { i++; } if(i < j) { swap(array[i], array[j]); } } //将基准temp放于自己的位置,(第i个位置) swap(array[low], array[i]); quick_sort(array, low, i - 1); quick_sort(array, i + 1, high); }