快速排序+插入排序

//思想依然是:递归
//关键:寻找枢纽元
//方法:三值中值
//问题,要是left==right时,如何用快速排序?该程序结合了插入排序
#include <iostream>
//#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 left, int right);
void InsertSort(int*a, int N);
int Median(int* a, int left, int right);
void quick2(int* a, int left, int right);

int Median(int* a, int left, int right)
{
    if(left>=right) return left ;
    int tmp = a[left]; 
    int n = right-left+1;
    int b[n] = {0};
    int i, j=0, k=n-1;
    for(i = left+1; i<=right; i++){
        if(a[i] <= tmp) 
            b[j++] = a[i];
        else
            b[k--] = a[i];
    }
        b[j] = tmp;

    for(i = left;i <= right;i++){
        a[i]=b[i-left];
        cout<<b[i-left]<<' ';
    }
    cout<<endl;
    return left+j;
}
void quick2(int* a, int left, int right)
{
    if(left>=right) return;//递归条件
    int m=Median(a, left, right);
    quick2(a, left, m-1);
    quick2(a, m+1, right);
    
}


//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]);
	//if()
	swap(&a[center], &a[right-1]);    
	return a[right-1];

	//返回枢纽元
}


//i向后移动,j向前移动
//直到while循环不满足
//此时交换a[i]和a[j]使得,前半部分<pivot, 后半部分>pivot
void Qsort(int* a, 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);
	}
	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);
	Qsort(arr, 0, N-1);
        //quick2(arr, 0, N-1);
       for(int i = 0; i < N; i++){
		cout<<arr[i]<<' ';
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值