快速选择排序(quickselect)--基于quicksort

来源:互联网 发布:迪联软件 编辑:程序博客网 时间:2024/06/08 10:56
//思想依然是:递归//关键:寻找枢纽元//方法:三值中值//问题,要是left==right时,如何用快速排序?该程序结合了插入排序//在快速排序的基础上,进行快速选择排序,最坏情况O(N2),最好情况O(N)//选择第m个最小元,对应位置m-1//对于快速选择排序,该算法节省的时间在于,它并没有对第m个数所在范围外的那一部分进行排序。。。。。//因此,输出的排序后数组,后半部分并没有进行排序//为了验证该想法,可以输出每次选取的枢纽元,进行比较#include <iostream>#include <string>//#define cutoff 3using 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>0a[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, 后半部分>pivotvoid 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;}

0 0