一、算法思路
希尔排序是对插入排序的一种改进。它实质上是先将待排序数组分组,然后对每个组进行直接插入排序。
选取适当的增量序列,把数组按照给定的步长分为若干组,然后对每个小组进行插入排序,直到增量序列递减为1排序完成。
二、代码实现
void ShellSort(int* arr, int N)
{
int tmp;
// 选取的增量序列为:N/2, N/2*2, ... , 1
for (int Increment=N/2; Increment>0; Increment/=2)
{
/**
* 以Increment为步长把输入数组分为若干组
*
* 第一趟循环:
* 第1组---------arr[0], arr[Increment]
* 第2组---------arr[1], arr[Increment+1]
* ...
* 第N/2组-------arr[Increment-1], arr[2*Increment-1]
*/
for (i=Increment; i<N; i++)
{
tmp = *(arr + i);
// 对每个分组进行插入排序
for (j=i; j>=Increment; j-=Increment)
{
if (tmp < *(arr + j - Increment))
*(arr + j) = *(arr + j - Increment);
else
break;
}
*(arr + j) = tmp;
}
}
}
三、性能分析
希尔排序的时间性能跟选取的增量序列有关,总的来说的时间复杂度小于O(N²)。甚至可以达到O(N^4/3)或O(N^5/4)
常用的增量序列有:
1、希尔增量:N/2, N/2², N/2³, ... , 1
2、Hibbard增量:2^k - 1, ... , 7, 3, 1
3、Sedgewick增量
希尔排序的性能在实践中是完全可以接受的,即使是对于数以万计的N也是如此。编程的简单特点使得它成为对适度大量的输入数据经常选用的算法。