4.希尔排序(相对较快,不稳定)

思想:

先确定一个间隔,我们从0开始,每经过一个间隔取一个数,把这些数分成一组,把这一组数用插入排序排好。然后将间隔逐渐变小,循环该过程。

为什么比插入排序的效率高?

因为如果1在比较后面的位置,它要排到最前面必须经过很多次交换。如果用希尔排序,因为有间隔,所以只需要很少的次数就能把1排到前面。这就是它能提高效率的地方。希尔排序也叫改进排序。

希尔排序在间隔较大的时候交换的次数比较少,间隔小的时候交换的距离比较近。但希尔排序是跳着排的,所以不稳定。

实现:

//希尔排序(也叫改进排序,是对插入排序的改进;时间复杂度为n**1.3,空间为1,不稳定)
//思想:将插入排序的每次插入后一个改成间隔为n的插入;
//即:逻辑上将间隔为N的数取出来组成一个新的数组,然后进行插入排序
//然后逐渐将间隔减小,最终使用间隔为1的时候即为插入排序
//因为是跳着排的,所以希尔排序不稳定
//改进点:1.间隔大时,每次交换的步数变大了
//      2.间隔小时,交换的次数变少了
//N最大取多少:1.希尔第一次N取数组长度的1/2,每次为N*1/2
//          2.Knuth序列 n=3k+1(<=length) 初始k=1;一般会更快
int k=1;
while(3*k+1<a.length){
    k=3*k+1;
}
while(k>0)
{
    for (int j = k; j < a.length; j++) {
         //一次以k为间隔的插入排序
        for (int i = j; i > k - 1; i-=k) {
            if (a[i] < a[i - k]) swap(a, i, i - k);
        }
    }
    k=(k-1)/3;
}