Python手撕排序演算法

2021-10-05 16:19:41 字數 3399 閱讀 2261

氣泡排序(公升序):

歸併排序(公升序):(分而治之)

每次在若干無序資料中查詢最小數,放在無序資料的首位。
1.從n個元素的列表中找最小值及其下標,與第乙個元素交換

2.從第二個元素開始的n-1個元素中找最小值及其下標,與第二個元素交換

3.以此類推,n-1輪後即為排好序的資料

a =[49

,38,65

,97,76

,13,27

,49]for i in

range

(len

(a)-1)

: m = i

for j in

range

(i+1

,len

(a))

:if a[j]

< a[m]

: m = j

temp = a[i]

a[i]

= a[m]

a[m]

= temp

第一輪比較:從第乙個元素開始,按順序對列表中所有n個元素中連續的兩個元素進行

兩兩比較,如果兩者不滿足公升序關係則交換。第一輪比較過後,最大數將下沉到列表最

後。第二輪比較:從第乙個元素開始,對列表中前n-1個元素進行兩兩比較,使次大數沉到

最後。依此類推,n-1輪後,排序完畢

演算法實現:

a=[77

,42,35

,12,101,5

]for i in

range

(len

(a)-1)

:for j in

range

(len

(a)-

1-i)

:if a[j]

> a[j+1]

: a[j]

,a[j+1]

=a[j+1]

,a[j]

print

(a)

演算法改進版:(某一輪比較中,一次交換也沒有執行過,就說明已經排好序了)

a=[77

,42,35

,12,101,5

]for i in

range

(len

(a)-1)

: flag =

true

for j in

range

(len

(a)-

1-i)

:if a[j]

> a[j+1]

: a[j]

,a[j+1]

=a[j+1]

,a[j]

flag =

false

if flag ==

true

:break

print

(a)

1.將包含n個元素的列表拆分成兩個含n/2個元素的子列表

2.對兩個子列表遞迴呼叫歸併排序(最後可以將整個列表分解為n個子列表)

3.合併兩個已排好序的子列表

演算法實現:

def

merge

(left, right)

:#合併兩個列表

merged =

i, j =0,

0#i和j分別作為left和right的下標

left_len, right_len =

len(left)

,len

(right)

#分別獲取左右子列表的長度

while i < left_len and j < right_len:

#迴圈歸併左右子列表元素

if left[i]

<= right[j]:)

#歸併左子列表元素

i +=

1else:)

#歸併右子列表元素

j +=

1 merged.extend(left[i:])

#歸併左子列表剩餘元素

merged.extend(right[j:])

#歸併右子列表剩餘元素

print

(left,right,merged)

#跟蹤除錯

return merged #返回歸併好的列表

defmergesort

(a):

#歸併排序

iflen

(a)<=1:

#空或者只有1個元素,直接返回列表

return a

mid =

len(a)//2

#列表中間位置

left = mergesort(a[

:mid]

)#歸併排序左子列表

right = mergesort(a[mid:])

#歸併排序右子列表

return merge(left, right)

#合併排好序的左右兩個子列表

a =[98,

23,45,

14,6,

67,33,

42]a1 = mergesort(a)

print

(a1)

python列表自帶有排序演算法:

a =[98

,23,45

,14,6

,67,33

,42]a.sort(

)#預設公升序排序

print

(a)#輸出[6, 14, 23, 33, 42, 45, 67, 98]

a =[98,

23,45,

14,6,

67,33,

42]a.sort(reverse=

true

)#降序排序

print

(a)#輸出[98, 67, 45, 42, 33, 23, 14, 6]

a =[98,

23,45,

14,6,

67,33,

42]b =sorted

(a)#降序採用sorted(a,reverse=true)

print

(a)#輸出[98, 23, 45, 14, 6, 67, 33, 42]不變

print

(b)#輸出[6, 14, 23, 33, 42, 45, 67, 98]

手撕演算法 排序

時間複雜度o n 2 o n 2 o n2 空間複雜度 o 1 穩定 從第乙個元素開始,認為左邊的序列是有序的,從有序部分的最後乙個向前比較,如果當前元素小於有序部分就交換,否則比較下乙個元素。function insertmerge arr else return arr let arr 1 5,...

演算法 手撕堆排序

時間複雜度 o n logn o nlogn o nlog n 但是實際軟開中,快排效能更好。堆性質 堆排序 從小到大,利用最大堆和陣列 從後往前堆化陣列元素,此時最大元素在首位置 交換元素堆化 include include using namespace std void heapsort in...

手撕演算法 adaboost

adaboost是典型的boosting演算法。boosting演算法的核心思想是 上乙個模型對單個樣本 的結果越差,下個模型越重視這個樣本 增大該樣本的權重,加大模型 錯的成本 提公升樹就是每個模型都是決策樹,提公升樹種效果比較好的是gbdt和xgboost,入門是adaboost。adaboos...