希尔排序的底层是插入排序,
不了解插入排序的友友可以先看我下面这篇文章:
插入排序详解-CSDN博客
思路
就整体而言,希尔排序不过是多用了几次插入排序,
预排序→插入排序,
预排序的作用是让数组元素更接近于有序,
以缩短最后插入排序的时间,
达到优化插入排序的效果。
预排序走的也是插入排序,
但是元素与元素之间的间隔不是1,而是gap(我们自己定义的,有计算公式),
而且gap会越来越小,
直至gap等于1,
就是正统的插入排序
画个粗略的图让大家理解一下:
下图有11个元素,
gap1=11/3+1=4,
gap2=gap1/3+1=4/3+1=2,
gap3=gap2/3+1=2/3+1=1.
建议大家看图时配合代码一起食用。
代码
void ShellSort(int* arr, int n)
{
int gap = n;
while (gap>1)
{
gap = gap / 3 + 1;//这条式子可以保证gap最后一定为1,走一遍插入排序
//i<n-gap,即i的最大值为n - gap - 1,保证数组不越界,因为tmep最大取到了arr[end + gap]
for (int i = 0; i < n - gap; i++)
{
//下面的框架和思想基本与插入排序一致
int end = i;
int temp = arr[end + gap];
while (end >= 0)
{
if (temp < arr[end])
{
arr[end + gap] = arr[end];
end -= gap;
}
else
{
break;
}
}
arr[end + gap] = temp;
}
}
}