排序–希爾排序

  • 2019 年 10 月 22 日
  • 筆記

圖片轉載於https://www.cnblogs.com/chengxiao/p/6104371.html

1、什麼是希爾排序?

希爾排序也是一種插入排序,他是第一個打破時間複雜度O(n^2)的排序方法,它與插入排序的不同之處在於,它會優先比較距離較遠的元素。希爾排序又叫縮小增量排序

2、希爾排序的思想:

希爾排序是把元素按下標的一定增量進行分組,對每組使用直接插入排序演算法排序;

隨著增量逐漸減少,當增量減至 1 時整個文件恰被分成一組,演算法便終止

3、程式碼逐步實現:

排序的元素:  int[] arr={8,9,1,7,2,3,5,4,6,0};

3.1 交換法實現

//第一步   for (int i=5;i<arr.length;i++){ //i的初始值為初始增量 10/2=5,分為5組,每組兩個元素              for (int j=i-5;j>=0;j-=5){  //j是距離i為5元素,那麼,0和5一組,6和2一組,以此類推,每組比完之後,回退到上一組重新比較,具體用法看第二輪                  if (arr[j+5]<arr[j]){  //比較大小,交換                      temp=arr[j];                      arr[j]=arr[j+5];                      arr[j+5]=temp;                  }              }          }          System.out.println(Arrays.toString(arr));

//第二次          for (int i=2;i<arr.length;i++){ //這裡的2是上次的5/2=2,所以分為兩組,一組5個              for (int j=i-2;j>=0;j-=2){//距離為2的元素,j-=2是每次比完這一輪重新指向上一分組比較,例如[3,1]和[1,0]兩組,比完[1,0]是[0,1],在和前面比較排序,最後為[0,1,3]                  if (arr[j+2]<arr[j]){                      temp=arr[j];                      arr[j]=arr[j+2];                      arr[j+2]=temp;                  }              }          }          System.out.println(Arrays.toString(arr));

 //第三次          for (int i=1;i<arr.length;i++){ //i是2/2=1,一共是一組              for (int j=i-1;j>=0;j-=1){                  if (arr[j+1]<arr[j]){                      temp=arr[j];                      arr[j]=arr[j+1];                      arr[j+1]=temp;                  }              }          }          System.out.println(Arrays.toString(arr));

最後把上面的程式碼整合起來:

 //匯總(交換法,花費時間長)          for (int a=arr.length/2;a>0;a/=2){  //a是增量              for (int i=a;i<arr.length;i++){                  for (int j=i-a;j>=0;j-=a){                      if (arr[j+a]<arr[j]){                          temp=arr[j];                          arr[j]=arr[j+a];                          arr[j+a]=temp;                      }                  }              }              System.out.println(Arrays.toString(arr));

上面才用交換的方式實現的排序花費時間大,不推薦使用,按照交換的思路繼續,替換成插入法

3.2 插入法實現:

 1  //匯總(基於插入,花費時間短)   2         for (int gap=arr.length/2;gap>0;gap/=2){   3             for (int i=gap;i<arr.length;i++){   4                     int j=i-gap;   5                     int temp=arr[i];   6                     while (j>=0 && temp<arr[j]){   7                         arr[j+gap]=arr[j];   8                         j-=gap;   9                 }  10                     arr[j+gap]=temp;  11             }  12             System.out.println(Arrays.toString(arr));  13  14         }

從3-10行都是插入法來實現的,可以看出,希爾排序就是對排序的元素進行分組,大大提升了時間

4、時間複雜度

O(n^(1.3—2))