快速排序 写法 版本 效率
Input:
10
72 6 57 88 60 42 83 73 48 85
Output:
6 42 48 57 60 72 73 83 85 88
1.挖坑填数+分治法
该方法的基本思想是:
1.1.先从数列中取出一个数作为基准数。
1.2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
1.3.再对左右区间重复第二步,直到各区间只有一个数。
针对洛谷P1177 【模板】快速排序代码如下:
#include <stdio.h>
#define maxn 100010
int a[maxn];
void qs(int left,int right){
int val,i,j;
val=a[left];//a[left]即a[i]就是第一个坑
i=left,j=right;
while(i<j){
while(i<j&&a[j]>val)j--;//从右向左找小于等于val的数来填a[i]
if(i<j)a[i]=a[j],i++;//将a[j]填到a[i]中,a[j]就形成了一个新的坑
while(i<j&&a[i]<val)i++;// 从左向右找大于等于val的数来填a[j]
if(i<j)a[j]=a[i],j--;//将a[i]填到a[j]中,a[i]就形成了一个新的坑
}
a[i]=val;//i==j,退出时,i等于j.将val填到这个坑中。
if(left<i)qs(left,i-1);
if(i<right)qs(i+1,right);
}
int main(){
int i,n;
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
qs(1,n);
printf("%d",a[1]);
for(i=2;i<=n;i++)printf(" %d",a[i]);
printf("\n");
return 0;
}
数据处理过程,部分如下:
位置1 2 3 4 5 6 7 8 9 10
数值72 6 57 88 60 42 83 73 48 85
处理区间[1,10],以a[1]=72为基准
i=1,j=10,j--
位置1 2(i) 3 4 5 6 7 8 9(j) 10
数值48 6 57 88 60 42 83 73 48 85
i=2,j=9,i++
位置1 2 3 4(i) 5 6 7 8(j) 9 10
数值48 6 57 88 60 42 83 73 88 85
i=4,j=8,j--
位置1 2 3 4 5(i) 6(j) 7 8 9 10
数值48 6 57 42 60 42 83 73 88 85
i=5,j=6,i++
位置1 2 3 4 5 6(i,j) 7 8 9 10
数值48 6 57 42 60 42 83 73 88 85
i=6,j=6
位置1 2 3 4 5 6(i,j) 7 8 9 10
数值48 6 57 42 60 72 83 73 88 85
1.分治区间[1,5]
位置1 2 3 4 5
数值48 6 57 42 60
处理区间[1,5],以a[1]=48为基准
i=1,j=5,j--
位置1 2(i) 3 4(j) 5
数值42 6 57 42 60
i=2,j=4,i++
位置1 2 3(i,j) 4 5
数值42 6 57 57 60
i=3,j=3,
位置1 2 3(i,j) 4 5
数值42 6 48 57 60
2.分治区间[7,10]
i=7,j=10
位置7 8 9 10
数值83 73 88 85
2.针对上述代码,进行写法的改进,改进的代码,并不意味着效率的提高。
针对洛谷P1177 【模板】快速排序代码如下:
#include <stdio.h>
#define maxn 100010
int a[maxn];
void qs(int left,int right){
int val,i,j,t;
val=a[left];
i=left,j=right;
while(i<j){
while(i<j&&a[j]>=val)j--;//=不能省
while(i<j&&a[i]<=val)i++;//=不能省
if(i<j) t=a[i],a[i]=a[j],a[j]=t;
}
a[left]=a[i],a[i]=val;//i==j。
if(left<i)qs(left,i-1);
if(i<right)qs(i+1,right);
}
int main(){
int i,n;
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
qs(1,n);
printf("%d",a[1]);
for(i=2;i<=n;i++)printf(" %d",a[i]);
printf("\n");
return 0;
}
3.针对上述代码,进行写法的改进,改进的代码,此时意味着效率的提高。
针对洛谷P1177 【模板】快速排序代码如下:
#include <stdio.h>
int a[100010];
void qs(int left,int right){//自小到大
int i=left,j=right,t;
int mid=a[(i+j)/2];//a[left];
while(i<=j){//结束时i>j
while(a[i]<mid)i++;
while(a[j]>mid)j--;
if(i<=j)t=a[i],a[i]=a[j],a[j]=t,i++,j--;
}
if(left<j) qs(left,j);
if(i<right) qs(i,right);
}
int main(){
int i,n;
scanf("%d",&n);
for(i=1;i<=n;i++) scanf("%d",&a[i]);
qs(1,n);
printf("%d",a[1]);
for(i=2;i<=n;i++) printf(" %d",a[i]);
printf("\n");
}