持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
题目
给定你一个长度为 n 的整数数列。
请你使用快速排序对这个数列按照从小到大进行排序。
并将排好序的数列按顺序输出。
输入格式
输入共两行,第一行包含整数 n。
第二行包含 n 个整数(所有整数均在 1∼10^9 范围内),表示整个数列。
输出格式
输出共一行,包含 n 个整数,表示排好序的数列。
数据范围
1 ≤ n ≤ 100000
输入样例:
5 3 1 2 4 5
输出样例:
1 2 3 4 5
思路
快速排序的模板
快速排序属于分治算法
分治算法步骤:
1.分成子问题
2.递归处理子问题
3.子问题合并
快速排序
有数组 arr, 左端点 l, 右端点r
确定划分边界 x
将 arr 分为 <=x 和 >=x 的两个小数组
i 的含义: i 之前的元素都 ≤ x, 即 q[l..i−1] ≤x
j 的含义: j 之后的元素都 ≥ x, 即 q[j+1..r] ≥x
结论: while 循环结束后, q[l..j] ≤x,q[j+1..r]≤x,
简单不严谨证明:
while 循环结束时, i≥j 若 i>j , 显然成立
若 i=j ∵ 最后一轮循环中两个 do−while 循环条件都不成立
∴ arr[i]≥x,arr[j]≤x
∴ arr[i] = arr[j] = x
∴ 结论成立
快速排序模板
void quick_sort(int arr[],int l,int r){
//递归的终止情况
if(l >= r) return;
//分成子问题
int x = arr[l + r + 1 >> 1],i = l - 1,j = r + 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;
}
}
//递归处理子问题
quick_sort(arr,l,i - 1);
quick_sort(arr,i,r);
//子问题合并,快速排序无需考虑此操作
}
ac代码
#include<iostream>
using namespace std;
int n;
const int N = 100010;
int arr[N];
void quick_sort(int arr[],int l,int r){
if(l >= r) return;
int x = arr[l + r + 1 >> 1],i = l - 1,j = r + 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;
}
}
quick_sort(arr,l,i - 1);
quick_sort(arr,i,r);
}
int main(){
cin >> n;
for(int i = 0;i < n;i++) cin >> arr[i];
quick_sort(arr,0,n - 1);
for(int i = 0;i < n;i++)cout << arr[i] << " ";
return 0;
}