P1177 【模板】排序 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
新学了快速排序,所以用快排做的。
算法思想:
快速排序:采用分治(分而治之)顾名思义就是把原来的数分为两部分
1.确定分界点q[l]或者q[(l+r)/2]或者q[r]随机选什么作为分界点都可以,但是注意,分界点不同,用的时长也会不一样,为了缩短时间,我们可以多尝试一下用谁做分界点好,(就比如我一开始用l爆掉了)但是如果没有时间限制的话,取谁作为分界点都无所谓。
2.调整区间-重中之重,代码的重要组成部分
小于分界点的放到左边,大于分界点的放在右边
3.递归处理左右两边
注意懂得算法思想之后还要熟练的写出代码,比如AC之后删除写3-5遍,对于我们初学者,背过也是一个挺好的策略。
原理讲解:假设我们有一组n=5的数组【3 1 2 4 5】
1.我们先设置一个左箭头l和右箭头r,初始下标为-1和n。当然数组中是无法索引到这个下标的,但是我们每次进行判断时先将l和r的值加一就不会出现数组越界的情况。再选一个分界点(最好使用q[(l+r)/2]· ,,因为这样更容易让两个子数组的长度划分的更接近,时间消耗会更短。
2,判断q[i]是否小于x,若小于则指针i加一指向下一个数,知道指到的数大于x停下来,也要保证i还在j的左边,此时轮到j指针开始行动,他判断q[j]是否大于x,如果大于就让指针向左移,直到指到的数小于x就停下来
3.此时左边得到了一个大于x的数,右边得到一个小于x的数,我们就将q[i]与q[j]的值交换,然后继续重复相同的步骤
4,最后一步就是运用递归思想,我们把左边的数组也用以上方法,右边子数组也是,最后一只判断到字数组的长度为一为止。
#include<stdio.h>
int a[100001];
void quick_sort(int a[],int l,int r){//快速排序
int i=l-1;
int j=r+1;
int x=a[(l+r)/2];
if(l>=r) return ;
while(i<j){
do{
i++;
}while(a[i]<x);
do{
j--;
}while(a[j]>x);
if(i<j){
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
quick_sort(a,l,j);
quick_sort(a,j+1,r);
}
int main(){
int n;
scanf("%d",&n);
int i;
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
quick_sort(a,0,n-1);
for(i=0;i<n;i++){
printf("%d ",a[i]);
}
return 0;
}