一、快速排序原理:
将原数列以x为分界线,分成左右两部分将这两部分再次以新的x为分界线分成左右两个部分,始终保证【左边小于x,右边大于x】,当原数列被分到只剩一个元素时,就完成完成“升序排列”。
二、排序思路——分治思想
- 思路一:
- 确定分界点:q[l],q[(l+r)/2],q[r](随机)
- 调整范围:使左边全部<=x,右边全部>=x
- 递归处理左右两段
2.思路二:暴力解法
- a[],b[]使用两个额外的空间->暴力解法
- q[[l~r]:q[i]<=x则x->a[];q[i]>=x则x->b[];a[]->q;b[]->q
3.思路三:双指针
- 定义双指针i,j,分别从当前数列首尾向中间运行。
- 先从左侧的i开始,如果i指向值小于x,说明满足要求则继续向右移动,一旦发现大于x的值,则停留,等待交换。
- 此时切换到j指针向左运动,如果j指向值大于x说明满足条件继续移动,一旦发现小于x的值,则停留,并将其和之前停留的i指向的值发生交换,之后再从i继续前进。
给定你一个长度为 n 的整数数列。
请你使用快速排序对这个数列按照从小到大进行排序。
并将排好序的数列按顺序输出。
输入格式
输入共两行,第一行包含整数 n。
第二行包含 nn个整数(所有整数均在 1∼范围内),表示整个数列。
输出格式
输出共一行,包含 n 个整数,表示排好序的数列。
数据范围
1≤n≤1000001≤n≤100000
输入样例:
5 3 1 2 4 5
输出样例:
1 2 3 4 5
-
#include<iostream> using namespace std; const int N=100010000; int n; int q[N]; void quick_sort(int q[],int l,int r){ if(l>=r) return; int x=q[l+r>>1],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]); } return 0; }
三、注意事项
1. eg:输入
2
1 2
用i则不能取到左边界,把x取值改成向上取整
用j则不能取到右边界,把x取值改成向下取整
取到边界会导致递归死循环
2.这个x=q[l+r>>1]是位运算 ,相当于除二。
int i = l - 1, j = r + 1, x = q[l + r >> 1];
3.数据加强情况下只能取中间值作为x