OC 希爾排序的理解

2021-08-06 02:21:27 字數 2166 閱讀 5977

oc:希爾排序的理解

作者皮蛋solo粥

2017.07.12 14:58*

字數 1492

希爾排序(shell sort),一聽這名字就知道是乙個叫希爾的外國人發明的排序。沒錯,他就是唐納德 希爾(donald shell),一位美國的計算機科學家,他於2023年發明的希爾排序演算法。

對於希爾排序,比較正式的官方的解釋是這樣:

希爾排序也是插入排序的一種。既然是其中的一種,那麼他們的區別是什麼呢?插入排序在最壞的情況下,即整個陣列是倒序的,此時時間複雜度達到了o(n2)。希爾排序在插入排序的基礎上增加乙個叫增量的概念。那什麼增量?插入排序只能與相鄰的元素進行比較,而希爾排序則是進行跳躍比較,而增量就是步長。比如增量為3時,下標為0的元素與下標為3的元素比較,3再與6比較,1與4比較,4再與7比較……想必你肯定做過一群人站成一排,按一二報數,喊一的一隊,喊二的一隊,此時的增量就是2。所以你也可以理解為是按增量進行了分組,再對每一組進行插入排序。當使用乙個增量對所有的分組排好序後,再去減少增量,重複之前步驟,直到增量為1,此時只有乙個分組了,再對這乙個分組進行插入排序,整個希爾排序就結束了(所以希爾排序也叫縮小增量排序,但顯然沒有希爾排序好聽和高大上 斜眼笑)。

從增量的初始值選取,到逐漸變為1,將所有用過的增量組成乙個序列,就是增量序列。而希爾排序的增量序列選擇直接影響它的時間複雜度(不要問我為什麼,我也不知道)。最簡單的增量就是希爾鼓勵使用的希爾增量。增量初始值選擇為n/2(n為陣列長度),然後每次將增量除以2,得到下乙個增量。所以它的增量序列為。除了希爾增量還有hibbard 增量knuth增量等等都是很複雜的數學公式,我怕你看了暈,就放在後面介紹吧!(說的好像自己看了不暈一樣)

那下面我們就以最簡單的希爾增量來進行希爾排序。

void shellsort (nsmutablearray *array) 

}[array exchangeobjectatindex:i withobjectatindex:minindex];

}}void insertionsort (nsmutablearray *array) else

}}}

三個同樣的陣列,分別使用選擇、插入、希爾進行排序比較時間。

int main(int argc, const char * argv) 

return 0;

}

陣列長度1萬時列印結果為:

2017-07-12 14:14:22.484 排序比較[14883:1166946] 插入排序用時:1.848809 s

2017-07-12 14:14:25.161 排序比較[14883:1166946] 選擇排序用時:2.675773 s

2017-07-12 14:14:25.179 排序比較[14883:1166946] 希爾排序用時:0.017643 s

陣列長度為兩萬時列印結果為:

2017-07-12 14:15:59.069 排序比較[14899:1169188] 插入排序用時:6.654105 s

2017-07-12 14:16:07.687 排序比較[14899:1169188] 選擇排序用時:8.615417 s

2017-07-12 14:16:07.726 排序比較[14899:1169188] 希爾排序用時:0.039497 s

差距是很明顯的。

希爾排序為不穩定性排序。因為相同的元素可能在各自的插入排序中移動,所以它的穩定性就被打破了。可能有人想問,穩定性是幹嘛的啊?穩定的意思是指相同的元素在排序後的相對位置不變。比如有兩個5 ,作為區分前面的叫51,後面的叫52,排序完成後51還在52的前面。那你可能會問,反正是一樣的,換了就換唄。但是在實際應用中被排序的物件會擁有不同的屬性,舉個栗子,公司在招聘時,想要年齡小的,所以對所有人進行了按年齡的排序。之後還想看成績分數高的。所以在按成績進行排序時就有可能出現成績一樣的,但他們的年齡不一樣,而你不能把成績相同但年齡大的排在小的前面。此時演算法的穩定性就有了意義。

使用希爾增量,在最壞的情況下時間複雜度仍為o(n2),而使用hibbard增量在最壞的情況下卻為o(n3/2)。

希爾排序的理解

希爾排序是插入排序的一種高效演算法,遞增量排序。我理解為步數排序 因為每次進行一次迴圈的時候,會給這次迴圈乙個跨度 也就是你一次能邁多少步 void sort int a,int length int step 0 這個while迴圈,目的是找出對於當前陣列下,最大的步數,也就是最多能擴多少,到最後...

希爾排序的理解

public static void shellsort int arr int j int temp for int gap arr.length 2 gap 0 gap 2 for int i gap i 這裡的 i gap就是插入排序的第二個數,j就是第乙個位置的數,i之所以是加一也要理解,當...

希爾排序理解

插入排序的 演算法複雜度為o n2 但如果序列為正序可提高到o n 而且直接插入排序演算法比較簡單,希爾排序利用這兩點得到了一種改進後的插入排序。希爾排序 將無序陣列分割為若干個子串行,子串行不是逐段分割的,而是相隔特定的增量的子串行,對各個子串行進行插入排序 然後再選擇乙個更小的增量,再將陣列分割...