像冒泡排序一樣,插入排序算法也易於實現和理解。但是與冒泡排序不同,它通過將每個項目與列表的其餘部分進行比較並將其插入正確的位置,來一次構建一個列表。此「插入」過程為算法命名。
一個很好的類比來解釋插入排序是您對一副紙牌進行排序的方式。想像一下,您手裡拿著一組卡片,並且想要按順序排列它們。首先,將一張卡片與其餘卡片進行逐步比較,直到找到正確的位置為止。屆時,您需要將卡插入正確的位置,然後重新開始製作新卡,重複進行直到您手上的所有卡都被排序為止。
在Python中實現插入排序
插入排序算法的工作原理與紙牌示例完全相同。這是Python中的實現:
與冒泡排序不同,此插入排序的實現通過將較小的項目向左推來構造排序列表。讓我們insertion_sort()逐行細分:
第4行建立了一個循環,該循環確定key_item函數在每次迭代期間的位置。請注意,循環從列表中的第二個項目開始,一直到最後一個項目。第7行key_item使用函數嘗試放置的項目進行初始化。第12行初始化一個變量,該變量將連續指向左側的每個元素key item。這些是將與連續比較的元素key_item。第18行key_item使用while循環將每個值與左側的值進行比較,將元素移位以留出放置空間key_item。第27行在算法將所有較大的值向右移動之後將key_item放置在正確的位置。下圖顯示了對數組進行排序時算法的不同迭代[8, 2, 6, 4, 5]:
現在,這裡是對數組進行排序時算法步驟的摘要:
該算法始於key_item = 2子數組,然後通過其左側的子數組以找到正確的位置。在這種情況下,子數組為[8]。由於2 < 8,算法會將元素8向右移動一個位置。此時的結果數組為[8, 8, 6, 4, 5]。由於子key_item數組中沒有其他元素,因此將放置在新位置,最終數組為[2, 8, 6, 4, 5]。第二遍從key_item = 6此處開始並經過位於其左側的子數組,在這種情況下為[2, 8]。由於6 < 8,算法向右移8。此時的結果數組為[2, 8, 8, 4, 5]。由於6 > 2,該算法不需要繼續遍歷子數組,因此可以定位key_item並完成第二遍。此時,結果數組為[2, 6, 8, 4, 5]。列表的第三遍將元素放置4在正確的位置,第四遍將元素5放置在正確的位置,對數組進行排序。測量插入排序的大O運行時複雜度
與您的冒泡排序實現類似,插入排序算法具有兩個嵌套循環,遍歷整個列表。內部循環非常有效,因為它僅遍歷列表,直到找到元素的正確位置為止。也就是說,該算法在平均情況下仍具有O(n 2)運行時複雜度。
最壞的情況發生在所提供的數組以相反順序排序時。在這種情況下,內部循環必須執行每個比較,以將每個元素放置在正確的位置。這仍然使您的運行時複雜度為O(n 2)。
最好的情況是對提供的數組進行了排序。在這裡,永遠不會執行內部循環,這會導致O(n)運行時複雜性,就像冒泡排序的最佳情況一樣。
儘管冒泡排序和插入排序具有相同的Big O運行時複雜性,但實際上,插入排序比冒泡排序有效得多。如果您查看兩種算法的實現,那麼您將看到插入排序如何減少對列表進行排序的比較。
定時插入排序實施
為了證明插入排序比冒泡排序更有效的主張,您可以對插入排序算法進行計時,並將其與冒泡排序的結果進行比較。為此,您只需要
run_sorting_algorithm()
使用插入排序實現的名稱替換對的調用:
您可以像以前一樣執行腳本:
shell
$ python sorting.py
Algorithm: insertion_sort. Minimum execution time: 56.71029764299999
請注意插入排序實現對相同數組進行排序的時間比冒泡排序實現少了大約17秒。儘管它們都是O(n2)算法,插入排序的效率更高。
分析插入排序的優點和缺點
就像冒泡排序一樣,插入排序算法的實現也很簡單。儘管插入排序是O(n 2)算法,但在實踐中它也比其他二次實現(例如冒泡排序)更有效。
有更強大的算法,包括合併排序和快速排序,但是這些實現是遞歸的,在處理小型列表時通常無法擊敗插入排序。如果列表足夠小,可以提供更快的整體實現,則某些快速排序實現甚至在內部使用插入排序。Timsort還在內部使用插入排序對輸入數組的一小部分進行排序。
也就是說,插入排序不適用於大型陣列,這為可以更有效地擴展規模的算法打開了大門。
關於算法的重要性,不用多說,python就是為大數據而生的,所有關於python算法的書籍,也有很多很多
補充:排序算法的重要性
排序算法是計算機科學中研究最深入的算法之一。您可以使用許多不同的排序實現和應用程式來使代碼更高效。
您可以使用排序來解決各種問題:
搜索:如果對列表進行排序,則搜索列表中的項目會更快。選擇:使用排序後的數據,可以根據列表與其餘項目的關係從列表中選擇項目。例如,當值以升序或降序排列時,找到第k 個最大或最小值,或找到列表的中值會容易得多。重複項:對列表進行排序後,可以非常快速地找到列表中的重複值。分布:如果對列表進行排序,則分析列表中項目的頻率分布非常快。例如,使用排序列表查找最頻繁或最少出現的元素相對簡單。