排序算法——(2)Python实现十大常用排序算法
上期為大家講解了排序算法常見的幾個概念:
如果有遺忘的同學可以看排序算法——(1)簡介這篇文章復習一下。
今天將為大家介紹常用的十大排序算法中最簡單的五種(冒泡、選擇、插入、希爾、歸并),主要從:過程圖解、算法思想、代碼實現、算法分析這四個方面講解,建議大家看完之后自己動手練習加強記憶!
注:本文使用的復雜度均為最壞復雜度
一、冒泡排序
冒泡排序(Bubble Sort),是一種計算機科學領域的較簡單的排序算法。它重復地走訪過要排序的元素列,依次比較兩個相鄰的元素,一層一層的將較大的元素往后移動,其現象和氣泡在上升過程中慢慢變大類似,故成為冒泡排序。
1.過程圖解
2.算法思想
3.代碼實現
def bubble_sort(arr):"""冒泡排序"""# 第一層for表示循環的遍數for i in range(len(arr) - 1):# 第二層for表示具體比較哪兩個元素for j in range(len(arr) - 1 - i):if arr[j] > arr[j + 1]:# 如果前面的大于后面的,則交換這兩個元素的位置arr[j], arr[j + 1] = arr[j + 1], arr[j]return arr4.算法分析
冒泡排序是一種簡單直接暴力的排序算法,為什么說它暴力?因為每一輪比較可能多個元素移動位置,而元素位置的互換是需要消耗資源的,所以這是一種偏慢的排序算法,僅適用于對于含有較少元素的數列進行排序。
二、選擇排序
選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工作原理是每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,所以稱為:選擇排序
1.過程圖解
2.算法思想
3.代碼實現
def selection_sort(arr):"""選擇排序"""# 第一層for表示循環選擇的遍數for i in range(len(arr) - 1):# 將起始元素設為最小元素min_index = i# 第二層for表示最小元素和后面的元素逐個比較for j in range(i + 1, len(arr)):if arr[j] < arr[min_index]:# 如果當前元素比最小元素小,則把當前元素角標記為最小元素角標min_index = j# 查找一遍后將最小元素與起始元素互換arr[min_index], arr[i] = arr[i], arr[min_index]return arr4.算法分析
選擇排序和冒泡排序很類似,但是選擇排序每輪比較只會有一次交換,而冒泡排序會有多次交換,交換次數比冒泡排序少,就減少cpu的消耗,所以在數據量小的時候可以用選擇排序,實際適用的場合非常少。
三、插入排序
插入排序(Insertion-Sort)的算法描述是一種簡單直觀的排序算法。它的工作原理是通過構建有序序列,對于未排序數據,在已排序序列中從后向前掃描,找到相應位置并插入。
1.過程圖解
2.算法思想
3.代碼實現
def insertion_sort(arr):"""插入排序"""# 第一層for表示循環插入的遍數for i in range(1, len(arr)):# 設置當前需要插入的元素current = arr[i]# 與當前元素比較的比較元素pre_index = i - 1while pre_index >= 0 and arr[pre_index] > current:# 當比較元素大于當前元素則把比較元素后移arr[pre_index + 1] = arr[pre_index]# 往前選擇下一個比較元素pre_index -= 1# 當比較元素小于當前元素,則將當前元素插入在 其后面arr[pre_index + 1] = currentreturn arr4.算法分析
插入排序的適用場景:一個新元素需要插入到一組已經是有序的數組中,或者是一組基本有序的數組排序。
四、希爾排序
希爾排序(Shell’s Sort)是插入排序的一種又稱“縮小增量(間隔)排序”(Diminishing Increment Sort),是直接插入排序算法的一種更高效的改進版本,它與插入排序的不同之處在于,它會優先比較距離較遠的元素,該方法因D.L.Shell于1959年提出而得名。
1.過程圖解
2.算法思想
希爾排序的整體思想是將固定間隔的幾個元素之間排序,然后再縮小這個間隔。這樣到最后數列就成為了基本有序數列,而前面我們講過插入排序對基本有序數列排序效果較好。
已知的最增量式是由 Sedgewick 提出的 (1, 5, 19, 41, 109,…),該步長的項來自 9 * 4^i - 9 * 2^i + 1 和 4^i - 3 * 2^i + 1 這兩個算式。這項研究也表明 "比較在希爾排序中是最主要的操作,而不是交換。 用這樣增量式的希爾排序比插入排序和堆排序都要快,甚至在小數組中比快速排序還快,但是在涉及大量數據時希爾排序還是比快速排序慢。
3.代碼實現
def shell_sort(arr):"""希爾排序"""# 取整計算增量(間隔)值gap = len(arr) // 2while gap > 0:# 從增量值開始遍歷比較for i in range(gap, len(arr)):j = icurrent = arr[i]# 元素與他同列的前面的每個元素比較,如果比前面的小則互換while j - gap >= 0 and current < arr[j - gap]:arr[j] = arr[j - gap]j -= gaparr[j] = current# 縮小增量(間隔)值gap //= 2return arr4.算法分析
五、歸并排序
歸并排序(MERGE-SORT)是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法(Divide and Conquer)的一個非常典型的應用。歸并排序適用于子序列有序的數據排序。
1.過程圖解
2.算法思想
從上圖看分解后的數列很像一個二叉樹。
3.代碼實現
def merge_sort(arr):"""歸并排序"""if len(arr) == 1:return arr# 使用二分法將數列分兩個mid = len(arr) // 2left = arr[:mid]right = arr[mid:]# 使用遞歸運算return marge(merge_sort(left), merge_sort(right))def marge(left, right):"""排序合并兩個數列"""result = []# 兩個數列都有值while len(left) > 0 and len(right) > 0:# 左右兩個數列第一個最小放前面if left[0] <= right[0]:result.append(left.pop(0))else:result.append(right.pop(0))# 只有一個數列中還有值,直接添加result += leftresult += rightreturn result4.算法分析
總結
今天給大家介紹的五種排序是比較簡單的排序,建議大家自己動手敲幾遍代碼,書讀百遍,其義自現。要求大家必須理解&記住它們的算法原理,因為代碼是永遠記不住的,只要記住原理你就能用偽代碼實現。 為了方便大家記憶我在每個算法分析最后給出了自己的記憶方法,如果你有不理解的地方,歡迎在下方留言,同時也歡迎大家轉發分享!
總結
以上是生活随笔為你收集整理的排序算法——(2)Python实现十大常用排序算法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 排序算法——(1)简介
- 下一篇: websocket python爬虫_p