日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

python实现常见排序算法

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

python實現(xiàn)常見排序算法

快速排序

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

遞歸實現(xiàn)

def quicksort(array):if len(array) < 2: # 遞歸終止條件:數(shù)組少于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) # 列表拼接,左邊繼續(xù)調(diào)用自身排序,右邊同理#驗證結(jié)果 print(quicksort([1, 4, 2, 6, 4, 5, 8, 3])) #===>[1, 2, 3, 4, 4, 5, 6, 8]

時間復雜度

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

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

選擇排序

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

def selection_sort(array):for i in range(len(array)-1,0,-1): #產(chǎn)生[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

時間復雜度

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

冒泡排序

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

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

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

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: # 上個循環(huán)體循環(huán)一次保證最后一個數(shù)是最大的flag = False for j in range(len(array) - 2 - i, 0, -1): # 從倒數(shù)第二個數(shù)開始,從后往前再浮動比較一下if array[j - 1] > array[j]:array[j], array[j - 1] = array[j - 1], array[j]flag = Trueif not flag:breakreturn array

時間復雜度

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

插入排序

思想:認定第一個元素是有序,取出第二個元素進行判斷插入到左邊的正確位置上,這是一個內(nèi)循環(huán),外循環(huá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: # 如果操作就是有序序列,每次都執(zhí)行else退出循環(huán)體,提升效率break

時間復雜度

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

歸并排序:

思路:將數(shù)組拆分成一個一個的小數(shù)組,然后進行臨近合并,合并的時候進行判斷排序
遞歸實現(xià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# 循環(huán)體結(jié)束,對稱的數(shù)據(jù)都比較完了,可能出現(xiàn)不對稱的話,將剩余數(shù)據(jù)追加到slist中slist += left[L:]slist += right[R:]return slist def merge_sort(arr):if len(arr) < 2:return arr# 開始遞歸拆分數(shù)組mid = len(arr) // 2left_list = merge_sort(arr[:mid])right_list = merge_sort(arr[mid:])# 開始合并return merge(left_list,right_list)

時間復雜度

  • 最優(yōu)時間復雜度:O(nlogn)
  • 最壞時間復雜度:O(nlogn)
  • 穩(wěn)定性:穩(wěn)定

排序算法時空復雜度總結(jié)


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

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

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

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

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

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。