在前面文章中介紹的直接插入排序,它對於已經基本有序的數據進行排序,效率會很高,而若是對於最初的數據是倒序排列的,則每次比較都須要移動數據,致使算法效率下降。算法
希爾排序的基本思想就是:將須要排序的序列劃分爲若干個較小的序列,對這些序列進行直接插入排序,經過這樣的操做可以使須要排序的數列基本有序,最後再使用一次直接插入排序。數組
在希爾排序中首先要解決的是怎樣劃分序列,對於子序列的構成不是簡單地分段,而是採起將相隔某個增量的數據組成一個序列。通常選擇增量的規則是:取上一個增量的一半做爲這次子序列劃分的增量,通常初始值元素的總數量。ide
算法步驟:spa
初始化數組:排序
(1)使用元素總數量的一半(8)做爲增量,將數屈打成招劃分爲8個序列,對這8個序列分別進行排序it
(2)將增量縮小一半(值爲4),從新劃分子序列,獲得4個子序列,對這4個子序分別進行排序,獲得第2遍排序後的結果。table
(3)縮小增量爲2,獲得以下結果:class
(4)第4遍增量爲1,獲得最終的排序結果:效率
代碼實現:im
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] |