快速排序 的思想是 以最左边的数值为基准,将它放在一个位置,使左边的数都比它小,右边的数都比它大,然后递归
举个例子来说:
4,2,1,5,7,8,2,3,7 这9个数
首先sort(0,8) 以最左边a[0]=4为基准,经过一系列调整过程 变成这样 3 2 1 2 4 8 7 5 7,4现在的位置是4,而且左边都比它小,右边都比它大,然后我们递归sort(0,3) sort(5,8),这样一步一步将问题化小,求出结果
调整过程可以这样做:
前后两个指针,以 sort(0,8) 为例
1. 在后面找到一个比4小的数,交换位置并修改当前位置
数组变成这样 3,2,1,5,7,8,2,4,7
2.在前面找到一个比4大的数,交换位置并修改当前位置
数组变成这样 3,2,1,4,7,8,2,5,7
3.重复第一步
可以在纸上模拟一下~
代码为:
# include <stdio.h>
void swap(int *a,int i,int j){
int t = a[i];
a[i] = a[j];
a[j] = t;
}
int sort(int *a,int l,int r){
int s,t,cur;
s = l+1;
t = r;
cur = l;
while(t > s){
while(a[t] >= a[cur] && t>s){
t--;
}
swap(a,cur,t);
cur = t;
while(a[s] <= a[cur] && t>s){
s++;
}
swap(a,cur,s);
cur = s;
}
for(int i=0; i<=8; i++) printf("%d ",a[i]); printf("\n");
return cur;
}
void quick_sort(int *a,int l,int r){
if(l >= r) return;
int pos = sort(a,l,r);
quick_sort(a,l,pos-1);
quick_sort(a,pos+1,r);
}
void top_k(int *a,int l,int r,int sort_l,int sort_r){
if(l >= r) return;
int pos = sort(a,l,r);
if(pos-1 >= sort_r) {
top_k(a,l,pos-1,sort_l,sort_r);
} else if(pos+1 <= sort_l){
top_k(a,pos+1,r,sort_l,sort_r);
} else{
top_k(a,l,pos-1,l,pos-1);
top_k(a,pos+1,r,pos+1,r);
}
}
int main(){
int a[]={4,2,1,5,7,8,2,3,7};
quick_sort(a,0,8);
//top_k(a,0,8,0,4);
for(int i=0; i<=8; i++) printf("%d ",a[i]); printf("\n");
}
对应的就是代码中的top_k 函数,其实和 quick_sort 函数相差不大,只是加上判断条件,举个例子来说
如果我们想求前4大的数,那么 我们在第一次快排的时候 根本不用求 sort(5,8), 只需要sort(0,3)再递归 就能求出结果了
当然了,我们也可以较快速地求出 第k大的数 ,方法是 pos==k 就返回