【算法】排序04——代碼簡約而不簡單的希爾排序(含代碼實現)


 

一、希爾排序的效能簡介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)爲序列長度的一半)

如, [ 569874123

第二步,一個指針從序列的無序區(由各個小序列的無序區組成)由左向右遍歷,遍歷到的元素,將其插入對應小序列的有序區」

如, [ 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, 61, 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 }

 

最後,若是小夥伴以爲這篇博文對你有幫助的話,就點個推薦吧

相關文章
相關標籤/搜索