日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python实现常见排序算法

發布時間:2024/7/23 python 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python实现常见排序算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

python實現常見排序算法

快速排序

思想:取出第一個元素把它放到序列的中間某一個正確位置,以它進行分割成左邊和右邊,再分別對左邊和右邊進行取元素分割(遞歸)

遞歸實現

def quicksort(array):if len(array) < 2: # 遞歸終止條件:數組少于2則是一個元素或空元素無需排序return arrayelse:mid = array[0] # 先確定一個中間點less = [i for i in array[1:] if i <= mid] # 生成一個列表的元素全部小于等于中間基準點more = [i for i in array[1:] if i > mid] # 生成一個列表的元素全部大于中間基準點return quicksort(less) + [mid] + quicksort(more) # 列表拼接,左邊繼續調用自身排序,右邊同理#驗證結果 print(quicksort([1, 4, 2, 6, 4, 5, 8, 3])) #===>[1, 2, 3, 4, 4, 5, 6, 8]

時間復雜度

  • 最優時間復雜度:O(nlogn)
  • 最壞時間復雜度:O(n*n) ==>深度最壞的n,單層是n,所以n*n
  • 穩定性:不穩定

對O(nlogn)的類比通俗理解:
遞歸調用函數可以理解為二叉樹,調用樹的深度是O(log n),也就是要切分logn次,而調用的每一層次結構總共全部僅需要O(n)的時間,所以二者相乘得O(nlogn),我這里說的調用樹其實是調用棧后面也會詳細說道快速排序的時間復雜度。
在最好的情況,每次我們運行一次分區,我們會把一個數列分為兩個幾近相等的片段。這個意思就是每次遞歸調用處理一半大小的數列。

選擇排序

思想: 假設最后一個元素是最大值,現在要從左到右(除了最后一個)依次與最大值進行比較,如果大于最大值就將兩個位置進行交換。
代碼實現

def selection_sort(array):for i in range(len(array)-1,0,-1): #產生[n-1,n-2,...2,1]for j in range(i):if array[j] > array[i]:array[j], array[i] = array[i], array[j]return array

時間復雜度

  • 最優時間復雜度:O(n*n)
  • 最壞時間復雜度:O(n*n) ==>深度最壞的n,單層是n,所以n*n
  • 穩定性:不穩定

冒泡排序

思想:所謂冒泡,就是將元素兩兩之間進行比較,誰大就往后移動,直到將最大的元素排到最后面,接著再循環一趟,從頭開始進行兩兩比較,而上一趟已經排好的那個元素就不用進行比較了。
一級優化實現
考慮整數數組就是有序的特殊情況,設定一個變量為False,如果元素之間交換了位置,將變量重新賦值為True,最后再判斷,在一次循環結束后,變量如果還是為False,則break退出循環,結束排序。

def bubble_sort(array):for i in range(len(array) - 1): # 外層循環n次保證所有數都在正確的位置上flag = False # 標識for j in range(len(array) - 1 - i): #內層循環一次代表最后一個數就是最大的if array[j] > array[j + 1]:array[j], array[j + 1] = array[j + 1], array[j]flag = True # 只要需要進行交換,則進入循環改為Trueif not flag: #如果沒進入循環體說明原來的數據是有序的break # 直接跳出循環return array

二級優化實現
上面這種寫法還有一個問題,就是每次都是從左邊到右邊進行比較,這樣效率不高,你要考慮當最大值和最小值分別在兩端的情況。寫成雙向排序提高效率,即當一次從左向右的排序比較結束后,立馬從右向左來一次排序比較。

def bubble_sort(array):for i in range(len(array) - 1):flag = Falsefor j in range(len(array) - 1 - i):if array[j] > array[j + 1]:array[j], array[j + 1] = array[j + 1], array[j]flag = Trueif flag: # 上個循環體循環一次保證最后一個數是最大的flag = False for j in range(len(array) - 2 - i, 0, -1): # 從倒數第二個數開始,從后往前再浮動比較一下if array[j - 1] > array[j]:array[j], array[j - 1] = array[j - 1], array[j]flag = Trueif not flag:breakreturn array

時間復雜度

  • 最優時間復雜度:O(n) ==> 已經是有序的了
  • 最壞時間復雜度:O(n*n)
  • 穩定性:穩定==>每次判斷如果相等,那就不交換,位置不變

插入排序

思想:認定第一個元素是有序,取出第二個元素進行判斷插入到左邊的正確位置上,這是一個內循環,外循環遍歷不包括第一個元素的下標進行重復操作。

def insert_sort(array):for i in range(1, len(array)): j = i # 從第二個元素開始while j > 0 :if array[j-1] > array[j]:array[j-1], array[j] = array[j], array[j-1]j -= 1else: # 如果操作就是有序序列,每次都執行else退出循環體,提升效率break

時間復雜度

  • 最優時間復雜度:O(n)
  • 最壞時間復雜度:O(n*n)
  • 穩定性:穩定==> 如果數值相等,在代碼中對=不進行處理,所以也不交換位置保證原來的位置順序

歸并排序:

思路:將數組拆分成一個一個的小數組,然后進行臨近合并,合并的時候進行判斷排序
遞歸實現

def merge(left, right):"""合并排序"""L, R = 0, 0slist = []while L < len(left) and R < len(right):if left[L] <= right[R]:slist.append(left[L])L += 1else:slist.append(right[R])R += 1# 循環體結束,對稱的數據都比較完了,可能出現不對稱的話,將剩余數據追加到slist中slist += left[L:]slist += right[R:]return slist def merge_sort(arr):if len(arr) < 2:return arr# 開始遞歸拆分數組mid = len(arr) // 2left_list = merge_sort(arr[:mid])right_list = merge_sort(arr[mid:])# 開始合并return merge(left_list,right_list)

時間復雜度

  • 最優時間復雜度:O(nlogn)
  • 最壞時間復雜度:O(nlogn)
  • 穩定性:穩定

排序算法時空復雜度總結


這里只說一下快速排序和歸并排序
快速排序我們遞歸調用棧的思想來理解,結合我后一篇文章學習遞歸來理解。

最好的情況, 快速排序的每次選的中間值mid都是真正的中間值,調用棧的高度(函數調用層數)就為O(logn),而每層需要時間為O(n),因此整個算法需要的時間為O(n) * O(log n) = O(n log n)。這就是最佳情況。

最糟糕情況, 有O(n)層,因此該算法的運行時間為O(n) * O(n) = O(n2)。

最佳情況也是平均情況。 只要你每次都隨機地選擇一個數組元素作為基準值,快速排序的平均運行時間就將為O(n log n)。快速排序是最快的排序算法之一,也是D&C(分而治之)典范。

這里需要記住的是,快速排序一般情況下是比歸并排序的速度要快

總結

以上是生活随笔為你收集整理的python实现常见排序算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。