一、冒泡排序
這個算法的名字由來是因為越大的元素會經由交換慢慢“浮”到數列的頂端(升序或降序排列),就如同碳酸飲料中二氧化碳的氣泡最終會上浮到頂端一樣,故名“冒泡排序”。
-
比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
-
對每一對相鄰元素做同樣的工作,從開始第一對到結尾的最后一對。在這一點,最后的元素應該會是最大的數。
-
針對所有的元素重復以上的步驟,除了最后一個。
-
持續每次對越來越少的元素重復上面的步驟,直到沒有任何一對數字需要比較。
# !/usr/bin/env python # -*- coding: utf-8 -*- li = [99, 0, -1, 46, -87, 7, 17, 20 ] le = len(li) # 長度8 for i in range(le): # [0,7] 持續每次對越來越少的元素重復上面的步驟,直到沒有任何一對數字需要比較。 for j in range(le - i - 1): # 針對所有的元素重復以上的步驟,除了最后一個。 if li[j + 1] > li[j]: # 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。 li[j], li[j + 1] = li[j + 1 ], li[j] # 這里不要break, print (li)
二、選擇排序
選擇排序是一種簡單直觀的排序算法。它的工作原理是每一次從待排序的數據元素中選出最小(或最大)的一個元素,存放在序列的起始位置,然后,再從剩余未排序元素中繼續尋找最小(大)元素,然后放到已排序序列的末尾。以此類推,直到全部待排序的數據元素排完。 選擇排序是不穩定的排序方法。
# !/usr/bin/env python # -*- coding: utf-8 -*- li = [99, 0, -1, 46, -87, 7, 17, 20 ] le = len(li) # 長度8 for i in range(le): # [0,7] max_val = i # 記錄最大值的角標,我們先假設i為最大值 for j in range(i + 1, le): # 再去循環我們假設的最大值和其它值去逐個比較 if li[j] > li[max_val]: # 當有值比我們假設的最大值大時,我們記錄角標 max_val = j li[i], li[max_val] = li[max_val], li[i] # 這樣我們循環i次以后,我們就可以得到集合內的最大值,然后我們放在第i個位置, print (li)
為什么我們回收選擇排序是不穩定的排序呢?簡單地說就是所有相等的數經過某種排序方法后,仍能保持它們在排序之前的相對次序,我們就
說這種排序方法是穩定的。反之,就是非穩定的。例如我們要排序[
1
,
1
,
1
,
1
,
1
,
1
,
1
],實則我們排序之后,每一個1的順序是不會變化的,還是按照原來的顏色放置就是穩定排序。也就是說排序以后還是這樣的[
1
,
1
,
1
,
1
,
1
,
1
,
1
]
三、插入排序
插入排序是一種簡單直觀且穩定的 排序算法 。如果有一個已經有序的數據序列,要求在這個已經排好的數據序列中插入一個數,但要求插入后此數據序列仍然有序,這個時候就要用到一種新的排序方法—— 插入排序法 ,插入排序的基本操作就是將一個數據插入到已經排好序的有序數據中,從而得到一個新的、個數加一的有序數據,算法適用于少量數據的排序, 時間復雜度 為O(n^2)。 是穩定的排序方法 。插入算法把要排序的 數組 分成兩部分:第一部分包含了這個數組的所有元素,但將最后一個元素除外(讓數組多一個空間才有插入的位置),而第二部分就只包含這一個元素(即待插入元素)。在第一部分排序完成后,再將這個最后元素插入到已排好序的第一部分中。
插入排序的基本思想是:每步將一個待排序的記錄,按其關鍵碼值的大小插入前面已經排序的文件中適當位置上,直到全部插入完為止。
# !/usr/bin/env python # -*- coding: utf-8 -*- li = [9, 0, -1, 46, -87, 7, 17, 20 ] le = len(li) # 長度8 k = 0 # 記錄交換次數 for i in range(1 , le): val = li[i] # 先記下每次大循環走到的第幾個元素的值 j = i while j > 0 and li[j - 1] < val: # 循環次數j大于0 and 前一位數大于后一位數 li[j] = li[j - 1] # 將后一位數放到前面,根據值的大小排序 j -= 1 # 把前面的數放到后面 k += 1 li[j] = val # 已經找到了左邊排序好的列表里不小于val的元素的位置,把val放在這里 print (li) print (k)
?四、快速排序
快速排序是對冒泡排序的一種改進。
通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然后再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以 遞歸 進行,以此達到整個數據變成有序 序列 。
# !/usr/bin/env python # -*- coding: utf-8 -*- """ 1)設置兩個變量i、j,排序開始的時候:i=0,j=N-1; 2)以第一個數組元素作為關鍵數據,賦值給key,即key=A[0]; 3)從j開始向前搜索,即由后開始向前搜索(j--),找到第一個小于key的值A[j],將A[j]和A[i]互換; 4)從i開始向后搜索,即由前開始向后搜索(i++),找到第一個大于key的A[i],將A[i]和A[j]互換; 5)重復第3、4步,直到i=j; (3,4步中,沒找到符合條件的值,即3中A[j]不小于key,4中A[i]不大于key的時候改變j、i的值,使得j=j-1,i=i+1, 直至找到為止。找到符合條件的值,進行交換的時候i, j指針位置不變。另外,i==j這一過程一定正好是i+或j-完成的時候,此時令循環結束)。 """ li = [9, 0, -1, 46, -87, 7, 17, 20 ] le = len(li) def QuickSort(li, start, end): # 判斷end結束是否小于start開始,如果為false,直接返回 if start < end: i, j = start, end # 設置基準數 base = li[i] while i < j: # 如果列表后邊的數,比基準數大或相等,則前移一位直到有比基準數小的數出現 while (i < j) and (li[j] >= base): j = j - 1 # 如找到,則把第j個元素賦值給第個元素i,此時表中i,j個元素相等 li[i] = li[j] # 同樣的方式比較前半區 while (i < j) and (li[i] <= base): i = i + 1 li[j] = li[i] # 做完第一輪比較之后,列表被分成了兩個半區,并且i=j,需要將這個數設置回base li[i] = base # 遞歸前后半區 QuickSort(li, start, i - 1 ) QuickSort(li, j + 1 , end) return li sortli = QuickSort(li, 0, le - 1 ) print (sortli)
五、歸并排序
歸并排序是建立在歸并操作上的一種有效的排序算法,該算法是采用分治法的一個非常典型的應用。將已有序的子序列合并,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合并成一個有序表,稱為二路歸并。
# !/usr/bin/env python # -*- coding: utf-8 -*- def merge(a, b): c = [] h = j = 0 while j < len(a) and h < len(b): if a[j] < b[h]: c.append(a[j]) j += 1 else : c.append(b[h]) h += 1 if j == len(a): for i in b[h:]: c.append(i) else : for i in a[j:]: c.append(i) return c def merge_sort(lists): if len(lists) <= 1 : return lists middle = int(len(lists) / 2 ) left = merge_sort(lists[:middle]) right = merge_sort(lists[middle:]) return merge(left, right) if __name__ == ' __main__ ' : li = [9, 0, -1, 46, -87, 7, 17, 20, 2 ] print (merge_sort(li))
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
