希尔排序听起来有点难,其实很简单
前言
直接插入排序當待排序數據的順序和期望排序結果相反時,排序效率是最差的;上次聊到的折半插入排序只是減少有序列表的比較次數,而對于整體數據遍歷次數還是沒有得到優化;接下來要說的希爾排序就是針對整體數據進行優化,從而提升排序效率。
正文
1.1 希爾排序算法思想
希爾排序(Shell's Sort)是直接插入排序算法的改進版,又稱“縮小增量排序”(Diminishing Increment Sort);
算法思想
將待排序數據根據指定步長進行分組,分別進行直接插入排序;減小步長,重復分組,重復直接插入排序,直到步長為1時進行最后一次插入排序。
對于第一次步長可以根據需要自定義,但一般推薦會設置為元素個數除以2(lenght/2),后續的步長依次是上一次步長除以2(stepk=stepk-1/2),直到步長為1,如下圖:
image-20210407235130599上面說到步長可以理解為增量,而減少步長的過程,也就是縮小增量,即希爾排序又稱為縮小增量排序。
分組原理(第一次分組的step1=6/2=3):
第一組:0索引位的元素為2,0+step1的索引位為3,對應的元素是1,3+step1越界了,則第一組的元素為2、1;
第二組:1索引位的元素為5,1+step1的索引位為4,對應的元素是9,4+step1越界了,則第二組的元素為5、9;
第三組:2索引位的元素為6,2+step1的索引位為5,對應的元素是3,5+step1越界了,則第三組的元素為6、3;此時元素就分組完成了;
接下來的分組就依次遞減步長,即上一次步長除以2取整;然后根據新算出來的步長繼續將上一次的排序的結果分組即可;直到步長遞減到為1時,整體進行最后一次直接插入排序為止;
1.2 希爾排序算法實現與解析
代碼實現(升序):
代碼運行結果如下:
結果步驟解析:
步驟上圖步驟說明:
將原始數據array復制到新數組中arrayb中,這步的主要目的是后續不需要聲明額外臨時變量,也為了后續核心代碼實現邏輯簡單易懂,減少過多的判斷;0索引位也充當為哨兵位;
第一步根據元素個數算出第一次步長step1=3,根據步長將待排序數據進行虛擬分組,索引位為1的元素和索引位為1+step的元素為一組,索引位為2的元素和索引位為2+step的元素為一組,索引位為3的元素和索引位為3+step的元素為一組;則將待排序數據分為2、1;5、9;6、3 三組;
第二步開始遍歷每一組數據,針對每一組數據進行直接插入排序;首先是第一組數據2、1,將待排序數據1放入哨兵位(即0索引位),哨兵位的數據1和有序列表中的2進行比較,2大于1,則需要騰出空位,所以2移到分組中索引位為4的位置;然后將哨兵位的數據1插入到騰出的空位中;
第三步遍歷第二組數據5、9,首先將待排序數據9放入哨兵位(即0索引位),哨兵位的數據9和有序列表中的5進行比較,5小于9,則不需改變位置;
第四步遍歷第三組數據6、3,首先將待排序數據3放入哨兵位(即0索引位),哨兵位的數據3和有序列表中的6進行比較,6大于3,則需要騰出空位,所以6移到分組中索引位為6的位置;然后將哨兵位的數據3插入到騰出的空位中;
分組排序完成之后,最終得出第一次分組排序結果:
第一次分組排序完成之后,調整步長,繼續進行分組,由于第二次計算出的步長step2=step1/2=1,即將所有上一次分組的數據全部為一組進行最后一次直接插入排序即可;這里就不在重復演示了,具體步驟和之前說到的直接插入排序一樣,參照這篇大牛領導單獨找我聊了兩句:搞框架的同時別忘了算法。
通過第二次插入排序完成之后就得到最后的排序結果啦。
1.3 希爾排序算法分析
時間復雜度
時間復雜度最壞情況和直接插入排序的時間復雜一樣,都是O(n2),但有其他大神經過大量演示,希爾排序的時間復雜度一般為O(n(1.3~2)),比O(n2)性能好。
空間復雜度
在算法核心部分只采用了固定的幾個中間變量((i,j,step,arrayb[0])),所以算法過程中消耗的內存是一個常量,則空間復雜度為O(1);
穩定性
由于在排序過程中是根據步長將原始數據進行分組,這樣就可能會導致相同的元素分到不同組,在最終排序時就不能保證原來兩個相同元素的順序啦,所以希爾排序是不穩定的。
綜上所述,希爾排序的時間復雜度為O(n2),空間復雜度為O(1),是不穩定算法;
總結
到這里,插入排序的三種排序介紹完畢,下期開始介紹交換排序;這里先總結一下插入排序的相關關鍵點(下圖綠色部分);如下:
總結感謝小伙伴的:點贊、收藏和評論,下期繼續~~~
一個被程序搞丑的帥小伙,關注"Code綜藝圈",跟我一起學~~~
總結
以上是生活随笔為你收集整理的希尔排序听起来有点难,其实很简单的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NET问答:什么场景下应该选择 stru
- 下一篇: OxyPlot.SkiaSharp中文显