(九)希尔排序
步长数列选择斐波那契数列:
inline int Fibonacci(int n)
{
if(n == 0) return 0;
if(n == 1) return 1;
return Fibonacci(n-1) + Fibonacci(n-2);
}
/*!
* \brief Shell_Sequence
* 斐波那契数列除去0和1将剩余的数以黄金分区比的两倍的幂进行运算
* \param n
* \return
*/
int Shell_Sequence(int n)
{
if(n <= 0) return 0;
return (int)pow(Fibonacci(n+1),(1+sqrt(5.0)));
}
实现代码:
double ShellSort(int *data, int size)
{
double res = 0;
int tmp = size/2;
int sq[12] = {0};
int n = 0;
for(int i=1; i<13; i++)
{
sq[i-1] = Shell_Sequence(i);
if(sq[i-1] > tmp)
{
n = i-1;
break;
}
}
EClock<> Ek;
for(int i=n-1; i>=0; i--)
{
int m = size/sq[i]+1;
for(int j=0; j<sq[i]; j++)
{
for(int k=1; k<m; k++)
{
if(sq[i]*k + j < size)
{
int x = k;
tmp = data[sq[i]*x+j];
while(x > 0 && tmp < data[sq[i]*(x-1)+j])
{
data[sq[i]*x+j] = data[sq[i]*(x-1)+j];
x--;
}
data[sq[i]*x+j] = tmp;
}
}
}
}
res = Ek.microsecond();
return res;
}
测试结果:
单位:us
10 | 0.30187 |
20 | 0.60374 |
50 | 1.50935 |
100 | 4.528049 |
200 | 9.961708 |
500 | 30.48886 |
1000 | 64.90204 |
2000 | 153.3499 |
3000 | 211.9127 |
4000 | 268.0605 |
5000 | 441.032 |
6000 | 462.1629 |
7000 | 489.9349 |
8000 | 571.1379 |
9000 | 1103.636 |
10000 | 768.5609 |
20000 | 1643.38 |
50000 | 4595.064 |
100000 | 10715.48 |
200000 | 23810.59 |
500000 | 68887.02 |
800000 | 112927.4 |
1000000 | 152361 |