希尔排序 转载

Posted codeart007

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了希尔排序 转载相关的知识,希望对你有一定的参考价值。

希尔排序是对插入排序的一种改进算法,是一种分组插入排序,又称为缩小增量排序法。

希尔排序的时间复杂度与增量(即,步长gap)的选取有关。例如,当增量为1时,希尔排序退化成了直接插入排序,此时的时间复杂度为O(N²),而Hibbard增量(N/2)的希尔排序的时间复杂度为O(N3/2)。

 

(1)、主要步骤:

  1. 对一个数组长度为N的数组,取一个小于N的整数gap(gap称为步长)
  2. 根据该步长将数组分为若干个子数组,所有距离为gap的倍数的记录放在同一个子数组
  3. 对每个子数组进行插入排序
  4. 然后缩减gap的值,并重复上面的分组和排序
  5. 当gap==1时,整个数组就是有序的
 
(2)、演示过程:

下面以数列{80,30,60,40,20,10,50,70}为例,演示它的希尔排序过程。

 

第1趟:(gap=4)

 

当gap=4时,意味着将数列分为4个组: {80,20},{30,10},{60,50},{40,70}。 对应数列: {80,30,60,40,20,10,50,70}
对这4个组分别进行排序,排序结果: {20,80},{10,30},{50,60},{40,70}。 对应数列: {20,10,50,40,80,30,60,70}

第2趟:(gap=2)

 

当gap=2时,意味着将数列分为2个组:{20,50,80,60}, {10,40,30,70}。 对应数列: {20,10,50,40,80,30,60,70}
注意:{20,50,80,60}实际上有两个有序的数列{20,80}和{50,60}组成。
          {10,40,30,70}实际上有两个有序的数列{10,30}和{40,70}组成。
对这2个组分别进行排序,排序结果:{20,50,60,80}, {10,30,40,70}。 对应数列: {20,10,50,30,60,40,80,70}

第3趟:(gap=1)

 

当gap=1时,意味着将数列分为1个组:{20,10,50,30,60,40,80,70}
注意:{20,10,50,30,60,40,80,70}实际上有两个有序的数列{20,50,60,80}和{10,30,40,70}组成。
对这1个组分别进行排序,排序结果:{10,20,30,40,50,60,70,80}

public void sort(int[] arr) {  
    // gap为步长,每次减为原来的一半。  
    for (int gap = arr.length / 2; gap > 0; gap /= 2) {  
        // 共gap个组,对每一组都执行直接插入排序  
        for (int i = 0; i < gap; i++) {  
            group_sort(arr, arr.length, i, gap);  
        }  
    }  
}  
  
private void group_sort(int arr[], int n, int i, int gap) {  
    for (int j = i + gap; j < n; j += gap) {  
        // 如果a[j] < a[j-gap],则寻找a[j]位置,并将后面数据的位置都后移。  
        if (arr[j] < arr[j - gap]) {  
            int tmp = arr[j];  
            int k = j - gap;  
            while (k >= 0 && arr[k] > tmp) {  
                arr[k + gap] = arr[k];  
                k -= gap;  
            }  
            arr[k + gap] = tmp;  
        }  
    }  
}  

 

 

以上是关于希尔排序 转载的主要内容,如果未能解决你的问题,请参考以下文章

基本算法-希尔排序

排序算法一 || 希尔排序

排序算法之希尔排序

排序算法之希尔排序

排序之希尔排序

排序算法07----------------------希尔排序