1. 程式人生 > >希爾排序—高效排序算法

希爾排序—高效排序算法

Shell排序 shellSort 希爾排序 插入排序

在前面文章中介紹的直接插入排序,它對於已經基本有序的數據進行排序,效率會很高,而如果對於最初的數據是倒序排列的,則每次比較都需要移動數據,導致算法效率降低。

希爾排序的基本思想就是:將需要排序的序列劃分為若幹個較小的序列,對這些序列進行直接插入排序,通過這樣的操作可使需要排序的數列基本有序,最後再使用一次直接插入排序。

在希爾排序中首先要解決的是怎樣劃分序列,對於子序列的構成不是簡單地分段,而是采取將相隔某個增量的數據組成一個序列。一般選擇增量的規則是:取上一個增量的一半作為此次子序列劃分的增量,一般初始值元素的總數量。

  • 算法步驟:

初始化數組:

技術分享圖片

(1)使用元素總數量的一半(8)作為增量,將數屈打成招劃分為8個序列,對這8個序列分別進行排序

技術分享圖片

(2)將增量縮小一半(值為4),重新劃分子序列,得到4個子序列,對這4個子序分別進行排序,得到第2遍排序後的結果。

技術分享圖片

(3)縮小增量為2,得到如下結果:

技術分享圖片

(4)第4遍增量為1,得到最終的排序結果:

技術分享圖片

  • 代碼實現:

public class ShellSort {

public static void main(String[] args) {

int arr[]={32,24,95,45,75,22,95,49,3,76,56,11,37,58,44,19,81};

System.out.println("排序前:"+Arrays.toString(arr));

sort(arr);

System.out.println("排序後:"+Arrays.toString(arr));

}

public static void sort(int arr[]) {

int d=arr.length/2;

int x,j,k=1;

while(d>=1) {

for(int i=d;i<arr.length;i++) {

x=arr[i];

j=i-d;

//直接插入排序,會向前找所適合的位置

while(j>=0 && arr[j]>x) {

//交換位置

arr[j+d]=arr[j];

j=j-d;

}

arr[j+d]=x;

}

d=d/2;

System.out.println(""+ k++ +"趟:"+Arrays.toString(arr));

}

}

}

排序前:[32, 24, 95, 45, 75, 22, 95, 49, 3, 76, 56, 11, 37, 58, 44, 19, 81]

1趟:[3, 24, 56, 11, 37, 22, 44, 19, 32, 76, 95, 45, 75, 58, 95, 49, 81]

2趟:[3, 22, 44, 11, 32, 24, 56, 19, 37, 58, 95, 45, 75, 76, 95, 49, 81]

3趟:[3, 11, 32, 19, 37, 22, 44, 24, 56, 45, 75, 49, 81, 58, 95, 76, 95]

4趟:[3, 11, 19, 22, 24, 32, 37, 44, 45, 49, 56, 58, 75, 76, 81, 95, 95]

排序後:[3, 11, 19, 22, 24, 32, 37, 44, 45, 49, 56, 58, 75, 76, 81, 95, 95]

希爾排序—高效排序算法