希尔排序

希尔排序是简单插入排序的拓展,以发明人shell的名字来命名。希尔排序和快速排序一样,是突破了O(n2)界限的排序算法。

希尔排序对简单插入排序的改进

希尔排序主要针对简单插入排序插入过程中移动速度过慢的缺点进行改进。对于简单插入排序来说,序列中逆序的元素越多,则算法需要比较和移动的次数越多就越多。假设极端情况,有一降序序列{5,4,3,2,1},要通过插入排序变为升序序列,那尾元素1要想移动成为头元素,就需要比较四次,移动四次。

 

希尔排序的思想是,我们加快待插入元素向前移动的步骤,使其移动速度加快。那么如何加速呢。希尔排序提出了增量序列的概念,将数组中的某元素按照某增量分组,然后在每一组内实现简单插入排序。

一开始,增量比较大,位于数组较后的部分会飞快的向前移动,当增量减小,经过之前的排序,数组已经基本有序,只需要做轻微的改动,最后一次插入排序保证序列一定有序。

增量序列的选取

增量序列的选取是一个难题,目前还没能证明某种序列在任意初始序列下都能达到最佳性能。通常我们选用shell提出的增量序列,初始增量为数组长度的二分之一,然后不断将增量除以2,即增量序列长度为{length/2,length/4,...,1}。

注:插入排序的实现可以参考排序算法及三大简单排序算法介绍

 

代码实现:

 1 void shellSort(int a[],int length)
 2 {
 3     for(int gap = length/2;gap>0;gap/=2)
 4     {
 5         for(int i = gap;i<length;i++)
 6         {
 7             for(int j=i;j>=gap;j-=gap)
 8             {
 9                 if(a[j-gap]>a[j]) swap(a[j-gap],a[j]);
10                 else break;
11             }
12         }
13     }
14 }