我的理解是, 插入排序最适合两种场景: 1). 较为有序情况; 2). 元素较少的情况. 所以, 希尔排序的思路就是:
1. 先把原始集合分割为一个个较小的集合, 进行插入排序, 符合场景 2)
2. 再将 1 处理后的集合切割为更小的集合, 继续进行插入排序, 仍符合场景2)
3. 当每一子集合的元素个数都为 1 时, 对整体进行插入排序, 此时符合场景1)
template
void ShellSort (Container &container)
{
const int container_len = container.size ();
int sub_container_len = 1;
//设置合适的sub_container_len
while (sub_container_len < container_len / 3)
sub_container_len = sub_container_len * 3 + 1;
//不断缩小sub_container_len, 直到其为0
while (sub_container_len > 0){
//对间隔为sub_contianer_len 的元素进行插入排序
for (int i = sub_container_len; i < container_len; ++i)
for (int j = i;
( j >= sub_container_len) && (container[ j ] < container[ j - sub_container_len ]);
j -= sub_container_len)
swap (container[j], container[j - sub_container_len]);
sub_container_len = sub_container_len / 3;
}
}