來(lái)自:靜默虛空 鏈接:cnblogs.com/jingmoxukong/p/4303279.html 圖片來(lái)自網(wǎng)絡(luò) 希爾(Shell)排序又稱為縮小增量排序,它是一種插入排序。它是直接插入排序算法的一種威力加強(qiáng)版。 該方法因DL.Shell于1959年提出而得名。 希爾排序的基本思想是: 把記錄按步長(zhǎng) gap 分組,對(duì)每組記錄采用直接插入排序方法進(jìn)行排序。 隨著步長(zhǎng)逐漸減小,所分成的組包含的記錄越來(lái)越多,當(dāng)步長(zhǎng)的值減小到 1 時(shí),整個(gè)數(shù)據(jù)合成為一組,構(gòu)成一組有序記錄,則完成排序。 我們來(lái)通過(guò)演示圖,更深入的理解一下這個(gè)過(guò)程。 在上面這幅圖中: 初始時(shí),有一個(gè)大小為 10 的無(wú)序序列。 在第一趟排序中,我們不妨設(shè) gap1 = N / 2 = 5,即相隔距離為 5 的元素組成一組,可以分為 5 組。 接下來(lái),按照直接插入排序的方法對(duì)每個(gè)組進(jìn)行排序。 在第二趟排序中,我們把上次的 gap 縮小一半,即 gap2 = gap1 / 2 = 2 (取整數(shù))。這樣每相隔距離為 2 的元素組成一組,可以分為 2 組。 按照直接插入排序的方法對(duì)每個(gè)組進(jìn)行排序。 在第三趟排序中,再次把 gap 縮小一半,即gap3 = gap2 / 2 = 1。 這樣相隔距離為 1 的元素組成一組,即只有一組。 按照直接插入排序的方法對(duì)每個(gè)組進(jìn)行排序。此時(shí),排序已經(jīng)結(jié)束。 需要注意一下的是,圖中有兩個(gè)相等數(shù)值的元素 5 和 5 。我們可以清楚的看到,在排序過(guò)程中,兩個(gè)元素位置交換了。 所以,希爾排序是不穩(wěn)定的算法。 核心代碼 public void shellSort(int[] list) { 希爾排序的算法性能 連接時(shí)間復(fù)雜度 步長(zhǎng)的選擇是希爾排序的重要部分。只要最終步長(zhǎng)為1任何步長(zhǎng)序列都可以工作。 算法最開(kāi)始以一定的步長(zhǎng)進(jìn)行排序。然后會(huì)繼續(xù)以一定步長(zhǎng)進(jìn)行排序,最終算法以步長(zhǎng)為1進(jìn)行排序。當(dāng)步長(zhǎng)為1時(shí),算法變?yōu)椴迦肱判?,這就保證了數(shù)據(jù)一定會(huì)被排序。 不會(huì)以如此短的時(shí)間完成排序了。 已知的最好步長(zhǎng)序列是由Sedgewick提出的(1, 5, 19, 41, 109,…),該序列的項(xiàng)來(lái)自 這兩個(gè)算式。 這項(xiàng)研究也表明“比較在希爾排序中是最主要的操作,而不是交換?!庇眠@樣步長(zhǎng)序列的希爾排序比插入排序和堆排序都要快,甚至在小數(shù)組中比快速排序還快,但是在涉及大量數(shù)據(jù)時(shí)希爾排序還是比快速排序慢。 算法穩(wěn)定性 由上文的希爾排序算法演示圖即可知,希爾排序中相等數(shù)據(jù)可能會(huì)交換位置,所以希爾排序是不穩(wěn)定的算法。 直接插入排序和希爾排序的比較 直接插入排序是穩(wěn)定的;而希爾排序是不穩(wěn)定的。 直接插入排序更適合于原始記錄基本有序的集合。 希爾排序的比較次數(shù)和移動(dòng)次數(shù)都要比直接插入排序少,當(dāng)N越大時(shí),效果越明顯。 在希爾排序中,增量序列g(shù)ap的取法必須滿足:最后一個(gè)步長(zhǎng)必須是 1。 直接插入排序也適用于鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu);希爾排序不適用于鏈?zhǔn)浇Y(jié)構(gòu)。 JAVA版本 代碼實(shí)現(xiàn) 范例代碼中的初始序列和本文圖示中的序列完全一致。 1 package notes.javase.algorithm.sort; 運(yùn)行結(jié)果 排序前: 9 1 2 5 7 4 8 6 3 5 |
|
來(lái)自: 滄瀟雨浪 > 《DataStructure》