快速排序--三元选中值代码实现

  • 三元选中值代码实现

三点选中位主元,针对不同的Cutoff运行结果,以及是否使用Cutoff的运行结果

//北航机试2020/3/28
/*
头中尾三位取中
针对不同的数据量
*/

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<algorithm>

using namespace std;

#define MAXN  1000000

int Cutoff = 50;

void Insertion_Sort(int A[],int N)
{
    int p,i;
    int temp;
    for(p = 1;p<N;p++)
    {
        temp = A[p];
        for(i = p;i>=1&&temp<A[i-1];i--)
        {
            A[i] = A[i-1];
        }
        A[i] = temp;
    }
}

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]);
    /* 此时A[Left] <= A[Center] <= A[Right] */
    swap(A[Center],A[Right-1]);/* 将基准Pivot藏到右边*/
    /* 只需要考虑A[Left+1] … A[Right-2] */
    return A[Right-1];
}

void Qsort(int A[],int Left,int Right)
{
    //使用Cutoff阈值来优化快速排序
    int pivot,Low,High;
    //int Cutoff = 50;使用全局变量用来测试
    if(Cutoff <= Right-Left)/* 如果序列元素充分多,进入快排 */
    {
        pivot = Median3(A,Left,Right);//选主元
        Low = Left;//元素划分
        High = Right-1;
        while(1)
        {
            while(A[++Low]<pivot);
            while(A[--High]>pivot);
            if(Low<High) swap(A[Low],A[High]);
            else break;
        }
        swap(A[Low],A[Right-1]);
        Qsort(A,Left,Low-1);
        Qsort(A,Low + 1,Right);
    }
    else/* 元素太少,用简单排序 */
    {
        Insertion_Sort(A+Left,Right-Left+1);
    }
}

void Quick_Sort(int A[],int N)
{
    Qsort(A,0,N-1);
}

void print(int A[],int N)
{
    int i;
    for(i = 0;i<N;i++)
    {
        if(i == N-1)
            printf("%d\n",A[i]);
        else
            printf("%d ",A[i]);
    }
}
void test(int A[],int arg_Cutoff)
{
    Cutoff = arg_Cutoff;
    clock_t start,end;
    start = clock();
	Quick_Sort(A,MAXN);
	end = clock();
	printf("执行时间Cutoff=%d %f s\n",Cutoff,(double)(end-start)/CLOCKS_PER_SEC);
}

int A1[MAXN],A2[MAXN],A3[MAXN],A4[MAXN],A5[MAXN],A6[MAXN];

int main()
{


    int i;

    srand((unsigned)time(NULL));

	for(i = 0;i<MAXN;i++)
	{
		 A6[i] = A5[i]=A4[i] = A3[i]=A2[i] = A1[i] = rand();
	}
	test(A1,50);
	test(A2,100);
	test(A3,200);
	test(A4,300);
	test(A5,400);
	test(A6,1);

    return 0;
}
/*
MAXN = 100000(十万级)
执行时间Cutoff=50  0.014000 s
执行时间Cutoff=100 0.017000 s
执行时间Cutoff=200 0.023000 s
执行时间Cutoff=300 0.023000 s
执行时间Cutoff=400 0.026000 s

MAXN = 1000000(百万级) 注意此时的数组申请,应设置为全局变量,否则程序
执行时间Cutoff=50  0.139000 s
执行时间Cutoff=100 0.157000 s
执行时间Cutoff=200 0.190000 s
执行时间Cutoff=300 0.278000 s
执行时间Cutoff=400 0.280000 s

hahahaha 你发现了什么,在Cutoff为50的时候,运行的速度最快
但是如果不使用Cutoff呢?

MAXN = 1000000(百万万级) 发现区别不是很明显
执行时间Cutoff=50  0.143000 s
执行时间Cutoff=100 0.197000 s
执行时间Cutoff=200 0.205000 s
执行时间Cutoff=300 0.241000 s
执行时间Cutoff=400 0.283000 s
执行时间Cutoff=1   0.156000 s

MAXN = 10000000(千万级)  发现使用了cutoff的算法要快一些
执行时间Cutoff=50  1.470000 s
执行时间Cutoff=100 1.431000 s
执行时间Cutoff=200 1.622000 s
执行时间Cutoff=300 1.902000 s
执行时间Cutoff=400 2.210000 s
执行时间Cutoff=1   1.696000 s
*/

小结:

  • 快速排序非常快,在数据级别达到千万级别的时候运行速度才会上
  • 上述的实验结果间接表明:插入排序适合数据量较小(因为不同的Cutoff的运行时间不同)
  • 递归的时候确实会影响程序的运行(此处的递归和不使用递归(不使用的比较其实是有点问题的,因为是以Cutoff为限,决定是否递归,也就意味着,两者的递归深度没有那么那么的大)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值