希尔排序算法

前些天老师讲了个希尔算法,突然发现自己竟然没用过。然后当时自己也是一副没睡醒的状态,干脆就没听睡觉了。然后现在自己补回来吧。看了下算法,希尔排序的实质也就是分组插入排序,该方法又称缩小增量排序。

0X001 基本思想

先取一个增量n1,有P个数据,然后初始增量n1=P/2,然后每隔n1个数据,将两个数据进行比较排序。然后所有数据进行完一次比较之后,继续取增量n2=n1/2,也就是每次减半,然后知道增量n=1,完成比较排序之后,最后的数据就是有序的了。

详细过程如图:
希尔排序过程


0X002 代码实现

首先按照基本思想写出希尔排序的代码实现

void shellsort1(int a[], int n)  
{  
    int i, j, gap;  
    for (gap = n / 2; gap > 0; gap /= 2) //步长  
    for (i = 0; i < gap; i++)        //直接插入排序  
    {  
        for (j = i + gap; j < n; j += gap)   
            if (a[j] < a[j - gap])  
            {  
                int temp = a[j];  
                int k = j - gap;  
                while (k >= 0 && a[k] > temp)  
                {  
                    a[k + gap] = a[k];  
                    k -= gap;  
                }  
                a[k + gap] = temp;  
            }  
    }  
}  

上述代码很直观的表现了希尔排序的过程,但是代码不够简洁,还可以进一步优化。

void shellsort2(int a[], int n)  
{  
    int i, j, gap;  
    for (gap = n / 2; gap > 0; gap /= 2)  
        for (i = gap; i < n; i++)  
            for (j = i - gap; j >= 0 && a[j] > a[j + gap]; j -= gap)  
                Swap(a[j], a[j + gap]);  
}  

直接利用swap函数配合for循环,实现了希尔排序!


0X003 题外拓展

上面希尔的步长选择都是从n/2开始,每次减半,直到最后为1。然后在wiki上有更高效的步长选择。有兴趣可以点击链接阅读了解。
https://zh.wikipedia.org/wiki/%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8F

添加新评论