- 三元选中值代码实现
三点选中位主元,针对不同的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为限,决定是否递归,也就意味着,两者的递归深度没有那么那么的大)