當前位置:
首頁 > 知識 > 插入排序演算法之直接插入排序和希爾排序

插入排序演算法之直接插入排序和希爾排序


插入排序演算法

有一個已經有序的數據序列,要求在這個已經排好的數據序列中插入一個數,但要求插入後此數據序列仍然有序,這個時候就要用到一種新的排序方法——插入排序法,插入排序的基本操作就是將一個數據插入到已經排好序的有序數據中,從而得到一個新的、個數加一的有序數據。


直接插入排序

直接插入排序的排序思路是:每次將一個待排序的元素與已排序的元素進行逐一比較,直到找到合適的位置按大小插入。

例子:

有序列:

插入排序演算法之直接插入排序和希爾排序

開始時,有序序列只有一個元素就是第一個元素(紅色),後面的無序序列(綠色)。接下來,取無序序列中的第一個元素3,把它放到有序系列的合適位置。方法是,從有序序列的最後面向前,依次和3比較,如果比3大,就向後移動一個位置,直到找到比3小的元素,然後把3插到後面(由於後面的元素已經依次移動,所以該位置已經空出),或者有序序列中沒有比3小的元素,則將3放在有序序列的第一個位置(由於移動,該位置已經空出)。最後結果為:

插入排序演算法之直接插入排序和希爾排序

同樣,取無序隊列中的第一個元素,也就是6,然後,從有序序列的後面依次向前比較,首先是8,大於6,則向後移動(注意,8後移則會佔據6的位置,所以要提前將6存一份)。接著比較3和6,3比6小,所以將6插在3的後面(也就是原來8的位置,8已經後移,該位置已空)。所以結果就是:

插入排序演算法之直接插入排序和希爾排序

繼續下去,直到安排好最後一個元素。

代碼:

代碼也很簡單,主要的就是比較和後移,但要注意,要將待排序的元素多存一份,因為後移時,會佔據該元素的位置。

插入排序演算法之直接插入排序和希爾排序

時間複雜度

只是定性的一個分析:從代碼中可以看出,演算法的核心就是比較和移動,如果序列本身是有序的,那麼只需要n次比較,不需要移動,所以此時的時間複雜度為O(n)。如果序列是倒序的,則排第n個元素時,需要與前n-1個元素進行比較,前n-1個元素也都要後移。這樣n從1取到n就是,比較和移動的次數都是0+(2-1)+(3-1)+..+(n-1)結果就是n*(n-1)/2,所以是O(n2)級別。書上說,直接插入排序的平均時間複雜度也是O(n2)級別。

是否是穩定的

是的。(稍微想一下就知道)


希爾排序

希爾排序是希爾(Donald Shell)於1959年提出的一種排序演算法。希爾排序也是一種插入排序,它是簡單插入排序經過改進之後的一個更高效的版本,也稱為縮小增量排序,同時該演算法是衝破O(n2)的第一批演算法之一。

希爾排序演算法的時間複雜度和步長的選取有關,平均時間複雜度為O(nlog2n),最壞為O(n2),最好為O(n).

直接插入排序更適合於原始記錄基本有序的集合。這是因為如果記錄基本有序,那麼直接插入排序時移動的次數就會很少。而希爾排序正式利用了直接排序的這一個特點,希爾排序將數據按一定的步長進行分組,是的記錄很快就會達到整體基本有序。

例子:

有序列:

插入排序演算法之直接插入排序和希爾排序

首先選擇一個步長,前面說過不同的初始步長會導致不同的時間複雜度,書上說,希爾排序的步長選擇是一個數學難題,所以我們不要糾結。最常用的初始步長就是length/2。在這個例子中,length=9,所以初始步長step=4。然後我們將原序列分成四組(記住,步長是多少就分成多少組!!!!),分組的原則是,同一組中的元素中,每兩個元素之間的下標的差為步長step。分組結果如下(相同顏色為一組)

插入排序演算法之直接插入排序和希爾排序

然後,分別對每一組按照直接插入排序的方法進行排序(注意,此時每組中相鄰的兩個元素之間的下標差是步長step,而不是1)結果為:

插入排序演算法之直接插入排序和希爾排序

然後改變步長:step=step/2,所以這一輪的步長為2,然後將數組分成兩組(再次說明,步長是多少,就分多少組)。如下(相同顏色為一組):

插入排序演算法之直接插入排序和希爾排序

然後按照直接插入進行排序

插入排序演算法之直接插入排序和希爾排序

然後,繼續改變步長,step=step/2,所以這一輪的步長為1,此時素組就分成一組了:

插入排序演算法之直接插入排序和希爾排序

然後,按照直接插入排序進行排序,

插入排序演算法之直接插入排序和希爾排序

接下來改變步長,step=step/2,步長為0,結束。

寫代碼:

通過上面的例子我們可以看到,實際上對分成的每一個組,進行的操作還是直接插入排序,只不過處理時,要考慮相鄰兩個元素之間的下標差不在是1,而是step。所以,我們首先要對上面直接插入排序的函數insert_sort()進行必要的修改,加入兩個參數:首元素的下標(以確定是對哪一組數據進行直接排序)和步長。如下:

插入排序演算法之直接插入排序和希爾排序

最後主函數中,主要任務就是分組,然後對每組數據都調用insert_sort()函數,還是再次強調:step是多少就分多少組!!!

完整代碼

插入排序演算法之直接插入排序和希爾排序

插入排序演算法之直接插入排序和希爾排序

文章摘自博客園


更多乾貨推薦:

IT教育專業培訓:http://www.ujiuye.com/

IT職業在線教育:http://xue.ujiuye.com/

互聯網營銷集訓營:http://www.ujiuye.com/zt/zsjz/?wt.bd=lsh11tt

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 IT優就業 的精彩文章:

程序員的一天:不是在苦逼,就是在苦逼的路上
SpringMVC詳解——詳細架構
macvlan 網路隔離和連通-每天5分鐘玩轉 Dock
ASP.NET Core Razor頁面 vs MVC
ExoPlayer Talk 01 緩存策略分析與優化

TAG:IT優就業 |

您可能感興趣

什麼是插入排序演算法?