快速排序大家都熟悉,其中最为关键的是划分函数。我们一定要理解和应用划分的思想,这个可以解决很多问题,且听分析;
1.输出第K个小的数。大家很容易想到的是先排序一番,然后循环输出到第K个就是了。还容易想到的是小顶堆排序的算法。现在我来介绍一个新的方法,就是利用快排的划分思想
先来说说这个思想:首先找一个纽轴可以是随机的,也可以是第一个(为了方便就取第一个吧,其实选择这个纽轴有时候也很关键)。然后与高位比较如果比它小,高位的指针减一 否者与高位的数交换。类似,与地位比较。
算法大概:
priv=a[low];
while(low<high){
while(low<high&&priv<a[high])high–;
a[low]=a[high];
while(low<high&&priv>a[low])low++;
a[high]=a[low];
}
a[low]=priv;
我们模拟快速排序算法,就知道每次纽轴确定的值就是最后排序完之后的那个位置。所以我们不用全部排序完,也能在到那个位置。
if(low==k){
return a[low];
}else if(low>k){
//递归调用
}else{
//递归调用
具体代码:
int k_elem(int b[],int low,int high,int k){//i起始座标,j为终止座标,k为第k个小的座标
int proiv=b[low];
int tem_low=low;//临时的low,high
int tem_high=high;
while(low<high){
while(low<high&&proiv<=b[high])high--;
b[low]=b[high];
while(low<high&&proiv>=b[low])low++;
b[high]=b[low];
}
b[low]=proiv;
if(k==low){
return b[low];
}else if(k>low){
return k_elem(b,low+1,tem_high,k);
}else{
return k_elem(b,tem_low,low-1,k);
}
}
}
2.把一个数组的奇数放在偶数的前面
思想:从前想后找到一个偶数,在从后向前找到一个奇数,然后交换。
int i=0;j=len-1;
while(i<j){
while(i<j&&a[i]%2!=0)i++;//从前向后找奇数
while(i<j&&a[j]%2==0)j–;//从后向前找偶数
swap(a[i],a[j]);
i++;
j–;
}
具体代码:
#include<stdio.h>
void move(int a[],int n){
int i=0,j=n-1;
while(i<j){
while(i<j&&a[i]%2!=0)i++;
while(i<j&&a[j]%2==0)j--;
int temp=a[i];
a[i]=a[j];
a[j]=temp;
}
}
int main(){
int a[]={1,2,3,4,5,6,7,8,9,10};
move(a,10);
for(int i=0;i<10;i++){
printf("%d",a[i]);
}
return 0;
}
当然还有很多应用有待总结