一、ShellSort--希尔排序
本质上:希尔排序是gap>1时的预排序 + gap==1时的插入排序
特点:gap越大,大的数越快到后面,小的数越快到前面,越接近无序; gap越小,大的数越慢到后面,小的数越慢到前面,越接近有序。
1.思路
(1).第一步--预排序(接近有序)
(2).第二步--直接插入排序(有序)
2.实现
void ShellSort(int* a, int n)//针对数据量大的
{
一、单趟的插入
int gap = 3;
//1.第一个for是表示第几组
for (int j = 0; j < gap; ++j)为啥j<gap,因为gap是个组
距,全部数是被分为gap组的,
同组中的数间隔gap.包括间隔
中的数和本身,就只有gap个
{
//2.第二个for表示第j组中的第几个
for (int i = j; i < n - gap; i += gap)
{
int end = i;
int tmp = a[end + gap];
while (end >= 0)
{
if (tmp < a[end])
{
a[end + gap] = a[end];
end -= gap;
}
else
{
break;
}
}
a[end + gap] = tmp;
}
}
二、多趟的插入
1.法1 将每一组gap分开完成,先完成一组再完成另一组
//多趟的插入
// gap > 1时是预排序
// gap 最后一次等于1,是直接插入排序
int gap = n;
while (gap > 1)
{
gap = gap / 3 + 1;//官方规定的gap的缩减速度,当gap缩减到1时,则变为了插入排序
for (int j = 0; j < gap; ++j)//先完成一个的,再完成另一个
{ 为啥j<gap,因为gap是个组
距,全部数是被分为gap组的,
同组中的数间隔gap.包括间隔
中的数和本身,就只有gap个
for (int i = j; i < n - gap; i += gap)//为啥i<n-gap,因为下面要满足i+gap<n
{
int end = i;
int tmp = a[end + gap];
while (end >= 0)
{
if (tmp < a[end])
{
a[end + gap] = a[end];
end -= gap;
}
else
{
break;
}
}
a[end + gap] = tmp;
}
}
}
疑问:
1.for (int j = 0; j < gap; ++j) 为啥j<gap,因为gap是个组距,全部数是被分为gap组的,同组中的数间隔gap.包括间隔中的数和本身,就只有gap个
2.for (int i = j; i < n - gap; i += gap)//为啥i<n-gap,因为下面要满足i+gap<n ,
如int tmp = a[end + gap];
2.法2 所有gap组并发进行
//多趟的插入
// gap > 1时是预排序
// gap 最后一次等于1,是直接插入排序
int gap = n;
while (gap > 1)
{
gap = gap / 3 + 1;
for (int i = 0; i < n - gap; ++i)//gap组数据交替插入排序(优化)
{
int end = i;
int tmp = a[end + gap];
while (end >= 0)
{
if (tmp < a[end])
{
a[end + gap] = a[end];
end -= gap;
}
else
{
break;
}
}
a[end + gap] = tmp;
}
}