希尔排序是插入排序的一种(抽象且比前面两种复杂,一定要理解插入排序先。
是直接插入排序的一种优化(实践排序也不大)
整体思路:
先1.预排序(让数组接近有序)
2.插入排序
实现思路:
1.假设将所有数据分成gap组。假设是3
2.对每一组进行插入排序
3.每组代码实现(先看一组)
int gap = 3;
for (size_t i = 0; i < n - gap; i += gap)//n是总共的数据个数;
//gap=1就是普通的插入排序
{
int end = i;//先从0开始
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;
}
}
3.3组排序(3层)
int gap = 3;
for (int j = 0; j < gap; j++)//一共是分成了3组,循环3次,从0开始到2结束
{
for (size_t 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;
}
}
3.法二:2层循环
int gap=3;
for (size_t i = 0; i < n - gap; i++)//挨着一个一个来,不是先排完一组
{
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.3层循环:一组走完,2曾循环:挨着走(一般书上给的都是这个,所以都要理解)
效率上没有任何的区别:完成的东西是一样的只不过顺序不一样。只是过程上有差异
越界问题。
2.gap到底给多大?
gap越大肯定跳的越快,大的越容易到后面,但结果越不接近有序。
gap越小肯定跳的越慢,大的不越容易到后面,但结果越接近有序。
若gap为1,就是插入排序。
所以不能太大,不能太小。
因此期望走多组预排序,结论当是gap=n/m+1的时候最合适。