快速排序及快速选择问题
1. 快速排序
- 采取分治,通过找到一个中枢值,使得中枢值左边的数小于等于其值,右边大于其值。
- 递归求解问题
- 当每一个数被当做一次中枢值,这个数组已经有序
//挖坑填数+分治
//函数出口为l=r时
//把数组分成中枢两侧,采取两个指针,挖坑填数
void quickSort(int a[],int left,int right){
int l=left,r=right,key=a[l];
if(l<r){
while(l<r){
while(l<r && key<a[r])
r--;
a[l]=a[r];
while(l<r && key>=a[l])
l++;
a[r]=a[l];
}
a[l]=key;
quickSort(a,left,l-1); //左边递归,重复上面找中枢步骤
quickSort(a,l+1,right); //右边递归,重复上面找中枢步骤
}
}
2. 快速选择问题
快速选择问题。输入n个整数和一个正整数k(1≤k≤n),输出这些整数从小到大排序后的第k个(例如,k=1就是最小值)。n≤107。
在快速排序的基础上,只需要找到第k个作为中枢的值,即为有序数列的第k个数的数值
int quickSort1(int a[],int left,int right,int num){
//快速选择问题。输入n个整数和一个正整数k(1≤k≤n),输出这些整数从小到大排序后的第k个
//函数出口为 l==r==num 和快排有差别
int l=left,r=right,key=a[l];
if(l<r){
while(l<r){
while(l<r && key<a[r])
r--;
a[l]=a[r];
while(l<r && key>=a[l])
l++;
a[r]=a[l];
}
a[l]=key;
}
if(num==l) //此时出现要找的数组下标
return key;
if(num<l)
return quickSort1(a,left,l-1,num); //递归左区间求解 必须带return,否则函数没法一级一级返回
else
return quickSort1(a,l+1,right,num); //递归左区间求解 必须带return,否则函数没法一级一级返回
}
快速排序和快速问题完整代码
#include <iostream>
#include <cstring>
#include <time.h>
#include <stdlib.h>
#define N 10
using namespace std;
int quickSort1(int a[],int left,int right,int num){
//快速选择问题。输入n个整数和一个正整数k(1≤k≤n),输出这些整数从小到大排序后的第k个
//函数出口为 l==r==num 和快排有差别
int l=left,r=right,key=a[l];
if(l<r){
while(l<r){
while(l<r && key<a[r])
r--;
a[l]=a[r];
while(l<r && key>=a[l])
l++;
a[r]=a[l];
}
a[l]=key;
}
if(num==l)
return key;
if(num<l)
return quickSort1(a,left,l-1,num); //递归左区间求解 必须带return,否则函数没法一级一级返回
else
return quickSort1(a,l+1,right,num); //递归左区间求解 必须带return,否则函数没法一级一级返回
}
void quickSort(int a[],int left,int right){
int l=left,r=right,key=a[l];
if(l<r){
while(l<r){
while(l<r && key<a[r])
r--;
a[l]=a[r];
while(l<r && key>=a[l])
l++;
a[r]=a[l];
}
a[l]=key;
quickSort(a,left,l-1); //左边递归,重复上面找中枢步骤
quickSort(a,l+1,right); //右边递归,重复上面找中枢步骤
}
}
int a[N];
int b[N];
int main(){
unsigned seek=unsigned(time(NULL));
srand(seek);
cout<<"Array:"<<endl;
for(int i=0;i<N;i++)
{
a[i]=rand();
cout<<a[i]<<" ";
}
cout<<endl;
memcpy(b,a,sizeof(a));
quickSort(a,0,N-1);
int pos=3; //要查找数的位置
cout<<"Result:"<<endl;
for(int i=0;i<N;i++)
cout<<a[i]<<" ";
int ans=quickSort1(b,0,N-1,pos-1);
cout<<endl<<"部分排序:"<<endl; //通过打印这个数组,验证O(n)复杂度,不是全部操作,只操作一部分
for(int i=0;i<N;i++)
cout<<b[i]<<" ";
cout<<endl<<endl<<"第 "<<pos<<" 个数是:"<<ans<<endl;
return 0;
}
输出结果:
Array:
11973 4898 13514 6085 14958 17750 2789 2706 20714 19060
Result:
2706 2789 4898 6085 11973 13514 14958 17750 19060 20714
部分排序:
2706 2789 4898 6085 11973 17750 14958 13514 20714 19060第 3 个数是:4898