//思想依然是:递归
//关键:寻找枢纽元
//方法:三值中值
//问题,要是left==right时,如何用快速排序?该程序结合了插入排序
//在快速排序的基础上,进行快速选择排序,最坏情况O(N2),最好情况O(N)
//选择第m个最小元,对应位置m-1
//对于快速选择排序,该算法节省的时间在于,它并没有对第m个数所在范围外的那一部分进行排序。。。。。
//因此,输出的排序后数组,后半部分并没有进行排序
//为了验证该想法,可以输出每次选取的枢纽元,进行比较
#include <iostream>
#include <string>
//#define cutoff 3
using namespace std;
int Median3(int* a, int left, int right);
int swap(int* t1, int* t2);
void Qsort(int* a, int m, int left, int right);
void InsertSort(int*a, int N);
//for循环外,首先记录待插入数a
//for循环中,依次遍历前面各数,大值存放在后面位置
//for循环结束后,i为a应该插入的位置(要么不变,要么插入最前面)
void InsertSort(int*a, int N)
{
int i = 0, tmp = 0, j;
for(j = 1; j < N; j++){
tmp = a[j];
for(i = j; i > 0&&a[i-1] > tmp; i--) //因为用到了a[i-1],所以i>0
a[i]=a[i-1];
a[i]=tmp;
}
}
int k = 0;
//对数组首,中间,末尾,三个元素进行大小排序,最后得到left<center<right的关系
//最后将center元素作为枢纽元, 且放在倒数第二个位置
int Median3(int* a, int left, int right)
{
int center = (left+right)/2;
if(a[left] > a[center]) swap(&a[left], &a[center]);
if(a[left] > a[right]) swap(&a[left], &a[right]);
if(a[center] > a[right]) swap(&a[center], &a[right]);
swap(&a[center], &a[right-1]);
return a[right-1];
//返回枢纽元
}
//i向后移动,j向前移动
//直到while循环不满足
//此时交换a[i]和a[j]使得,前半部分<pivot, 后半部分>pivot
void Qsort(int* a, int m, int left, int right)
{
int i,j;
int pivot;
//if(left + cutoff <= right){
if(left + 3 <= right){
pivot=Median3(a,left, right);
k++; //为了看每次递归调用选取的枢纽元
cout<<pivot<<' '<<k<<endl; //为了看每次递归调用选取的枢纽元
i = left;
j = right-1;
for(;;){
while(a[++i]<pivot){}
while(a[--j]>pivot){}
if(i < j){
swap(&a[i],&a[j]);
}
else break;
}
swap(&a[i],&a[right-1]);//交换之后,枢纽元位于i,此时,a[i]作为中点
//递归策略,a[i]为两部分的分界点
//Qsort(a, left, i-1);
//Qsort(a, i+1, right);
//快速选择排序,相对于快速排序,只改变了以下四行内容以及函数的参数
if(m <=i)
Qsort(a, m ,left, i-1);
else if(m > i)
Qsort(a, m, i+1, right);
}
else//插入排序和快速排序结合,比始终用快速排序节省15%的时间,小数组(N<=20)插入排序效率高
InsertSort(&a[left],right-left+1);
}
swap(int* t1, int* t2)
{
int tmp = *t1;
*t1 = *t2;
*t2 = tmp;
}
int main()
{
int arr[12]={3,4,5,6,24,13,26,1,2,27,38,15};
//int N = sizeof(arr)/sizeof(int);
int M = 3;
Qsort(arr, M, 0, 11);
for(int i = 0; i < 12; i++){
cout<<arr[i]<<' ';
}
cout<<endl;
cout<<"arr["<<M<<"-1]"<<"="<<arr[M-1]<<endl;
}
快速选择排序(quickselect)--基于quicksort
最新推荐文章于 2024-08-15 14:31:23 发布