一、希爾排序的效能簡介java
希爾排序是插入排序的改進型,也所以,它的空間複雜度是O(1)。不過有趣的是,希爾排序的平均時間複雜度計與其增量有關,算起來較爲複雜,dalao們的研究認爲是O[n^(1.3 ~ 2)]之間。面試
其實相比於快排、歸併、堆排這些平均之間複雜度爲O [ nlog(n) ]的線性對數階排序,希爾排序並不佔優點(由於希排有亞二次時間界),但做爲第一批突破第二次時間屏障的算法之一的存在,我jio得仍是要重溫一下經典(實際上是面試愛考ORZ)。算法
二、本文中的一些定義shell
2.1——有序區與無序區spa
在本文中,對於一個任意一個無序的的序列:指針
如, [ 5, 6, 9, 8, 7, 4, 1, 2, 3 ]code
咱們把這個序列從邏輯上分爲有序區和無序區,並默認在開始排序前,第一個元素爲有序區,其他爲無序區。blog
如, [ 5, 6, 9, 8, 7, 4, 1, 2, 3 ] (綠色爲有序區,紅色爲無序區)排序
在咱們對其逐漸有序化的時候,依次從無序區中取出其第一個元素並插入有序區:io
如, [ 5, 6, 9, 8, 7, 4, 1, 2, 3 ] (有序區會增長,無序區會減小,同時無序區第一個元素前的元素必然在有序區)
2.2——按增量(gap)劃分多個序列
一個序列能夠按增量(gap)在邏輯上劃分爲gap個序列(關於的gap的取值,第一次取序列長度一半,以後再取用gap前要除2):
如, [ 5, 6, 9, 8, 7, 4, 1, 2, 3 ] gap = 9/2 = 4 ,即在邏輯上分紅4組小序列,同一小序列內的、邏輯上相鄰的元素,在序列中的小標差爲gap:
如, [ 5, 6, 9, 8, 7, 4, 1, 2, 3 ] 好比紅色小序列應該是[ 5, 7, 3 ],它們在原序列中的小標爲0、四、8,相差爲gap
三、希爾排序的流程
第一步,在邏輯上按gap將序列劃分爲gap個小序列。(第一次時取增量(gap)爲序列長度的一半)
如, [ 5, 6, 9, 8, 7, 4, 1, 2, 3 ]
第二步,一個指針從序列的無序區(由各個小序列的無序區組成)由左向右遍歷,遍歷到的元素,將其插入對應小序列的有序區」
如, [ 5, 6, 9, 8, 7, 4, 1, 2, 3 ] 指針最開始指向序列無序區第一個即7,7在第一個小序列裏,把它插入第一個小序列的有序區,
如, [ 5, 6, 9, 8, 7, 4, 1, 2, 3 ] 指針+1指向無序區新的第一個元素4,4在第二個小序列裏, 把它插入第二個小序列的有序區,
如, [ 5, 4, 9, 8, 7, 6, 1, 2, 3 ] 注意,這裏是插入到第二個小序列的有序區,因此四、6換位,而後指針+1。。。。操做同上
第三步,gap/=2後若小於1就結束了,不然回調第一步。
四、代碼
1 import java.util.Arrays; 2 public class Main { 3 public static void shellSort(int[] arr) { 4 int temp; 5 //控制增量(gap),增量將不斷/2直到小於1。(序列會在邏輯上按gap劃分爲gap個小序列) 6 for (int gap = arr.length/2; gap >0; gap/=2) { 7 //遍歷無序區(最開始>=gap的下標都屬於無序區) 8 //變量p_in_unorder始終指向當前序列的無序區的第一個元素的下標 9 for (int p_in_unorder = gap; p_in_unorder < arr.length; p_in_unorder++) { 10 /* 11 *p_in_order是小序列有序區內的下標指針 12 *p_in_unorder - gap 是當前小序列有序區的最後一個 13 *把當前無序區第一個元素插入對應小序列有序區 14 */ 15 for (int p_in_order = p_in_unorder-gap ; p_in_order >= 0 ; p_in_order-=gap) { 16 if(arr[p_in_order]>arr[p_in_order+gap]){ 17 temp = arr[p_in_order]; 18 arr[p_in_order] = arr[p_in_order+gap]; 19 arr[p_in_order+gap] = temp; 20 } 21 } 22 } 23 } 24 } 25 26 public static void main(String[] args) { 27 int[] arr = new int[]{5,6,9,8,7,4,1,2,3}; 28 shellSort(arr); 29 System.out.println(Arrays.toString(arr)); 30 } 31 }
最後,若是小夥伴以爲這篇博文對你有幫助的話,就點個推薦吧