C#——希尔排序

201 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

希尔排序,也叫缩小增量排序,是直接插入排序算法的一种更高效的版本,适合中级数量级的排序,属于非稳定排序算法。

希尔排序的原理是将整个待排序序列分割成为若干子序列分别进行插入排序。希尔排序算法是将数组的所有元素按照一定增量d分组,对每组内的数据实行插入排序,之后不断减小增量,每组内所包含的元素也越多,增量减少至1时,整个数组被分成一组,插入排序结束后整个数组的排序便完成。

然而对于大规模乱序数组插入排序很慢,因为它只会交换相邻的元素,因此元素只能一点一点的从数组的一端移动到另一端。例如,如果主键最小的元素正好在数组的尽头,要将它挪到正确的位置就需要N-1次移动。希尔排序为了加快速度简单的改进了插入排序,交换不相邻的元素以对数组的局部进行排序,并最终用插入排序将局部有序的数组排序。

举个例子:

int[] sort = new int[13] { 1, 4, 89, 34, 56, 40, 59, 60, 39, 1, 40, 90, 48 }; 
int h = 1;
int length = sort.Length;
while (h > length / 3)
{
    h = 3 * h + 1;      // 1,4,13,40,121,364,1093,...
} 
while (h >= 1)
{
    for (int i = h; i < length; i++)
    {
        for (int j = i; j >= h && sort[j] < sort[j - h]; j -= h) 
         {
            int temp = sort[j];
            sort[j] = sort[j - h];
            sort[j - h] = temp;
         }
    }
    h = h / 3;
}
for (int i = 0; i < sort.Length; i++) 
{
    Console.Write(sort[i] + " ");
}

总而言之,希尔排序对插入排序的升级主要就是加入了一个步长的概念,通过步长每次可以把原序列分为多个子序列,对子序列进行插入排序,能够在极限情况下可以有效降低普通插入排序的时间复杂度,提升算法效率。