本篇主要實現九(八)大排序算法,分別是冒泡排序,插入排序,選擇排序,希爾排序,歸併排序,快速排序,堆排序,計數排序。但願你們回顧知識的時候也能從個人這篇文章獲得幫助。
爲了防止誤導讀者,本文全部概念性內容均截取自對應Wikipython
冒泡排序(Bubble Sort)是一種簡單的排序算法。它重複地走訪過要排序的數列,一次比較兩個元素,若是他們的順序錯誤就把他們交換過來。走訪數列的工做是重複地進行直到沒有再須要交換,也就是說該數列已經排序完成。這個算法的名字由來是由於越小的元素會經由交換慢慢「浮」到數列的頂端。git
冒泡排序算法的運做以下:github
def bubble_sort(list): length = len(list) # 第一級遍歷 for index in range(length): # 第二級遍歷 for j in range(1, length - index): if list[j - 1] > list[j]: # 交換二者數據,這裏沒用temp是由於python 特性元組。 list[j - 1], list[j] = list[j], list[j - 1] return list
這種排序其實還能夠稍微優化一下,添加一個標記,在排序已完成時,中止排序。算法
def bubble_sort_flag(list): length = len(list) for index in range(length): # 標誌位 flag = True for j in range(1, length - index): if list[j - 1] > list[j]: list[j - 1], list[j] = list[j], list[j - 1] flag = False if flag: # 沒有發生交換,直接返回list return list return list
選擇排序(Selection sort)是一種簡單直觀的排序算法。它的工做原理大體是將後面的元素最小元素一個個取出而後按順序放置。shell
def selection_sort(list): n=len(list) for i in range (0,n): min = i for j in range(i+1,n): if list[j]<list[min]: min=j list[min],list[i]=list[i],list[min] return list
插入排序(Insertion Sort)是一種簡單直觀的排序算法。它的工做原理是經過構建有序序列,對於未排序數據,在已排序序列中從後向前掃描,找到相應位置並插入。數組
def insert_sort(list): n = len(list) for i in range(1, n): # 後一個元素和前一個元素比較 # 若是比前一個小 if list[i] < list[i - 1]: # 將這個數取出 temp = list[i] # 保存下標 index = i # 從後往前依次比較每一個元素 for j in range(i - 1, -1, -1): # 和比取出元素大的元素交換 if list[j] > temp: list[j + 1] = list[j] index = j else: break # 插入元素 list[index] = temp return list
希爾排序,也稱遞減增量排序算法,是插入排序的一種更高效的改進版本。希爾排序是非穩定排序算法。
希爾排序是基於插入排序的如下兩點性質而提出改進方法的:
插入排序在對幾乎已經排好序的數據操做時,效率高,便可以達到線性排序的效率
但插入排序通常來講是低效的,由於插入排序每次只能將數據移動一位。數據結構
每次以必定步長(就是跳過等距的數)進行排序,直至步長爲1.app
def shell_sort(list): n = len(list) # 初始步長 gap = round(n / 2) while gap > 0: for i in range(gap, n): # 每一個步長進行插入排序 temp = list[i] j = i # 插入排序 while j >= gap and list[j - gap] > temp: list[j] = list[j - gap] j -= gap list[j] = temp # 獲得新的步長 gap = round(gap / 2) return list
步長使用的是Donald Shell的建議,另外步長還可使用Sedgewick提出的(1, 5, 19, 41, 109,...)。
也可使用 斐波那契數列除去0和1將剩餘的數以黃金分區比的兩倍的冪進行運算獲得的數列。
歸併操做(歸併算法),指的是將兩個已經排序的序列合併成一個序列的操做。歸併排序算法依賴歸併操做。less
假設序列共有n個元素:ide
# 遞歸法 def merge_sort(list): # 認爲長度不大於1的數列是有序的 if len(list) <= 1: return list # 二分列表 middle = len(list) // 2 left = merge_sort(list[:middle]) right = merge_sort(list[middle:]) # 最後一次合併 return merge(left, right) # 合併 def merge(left, right): l,r=0,0 result=[] while l<len(left) and r<len(right): if left[l] <right[r]: result.append(left[l]) l+=1 else: result.append(right[r]) r +=1 reslut +=left[l:] result+=right[r:] return result
鄙人不才,不知歸併排序的迭代法如何用Python實現,望指教。
快速排序使用分治法(Divide and conquer)策略來把一個序列(list)分爲兩個子序列(sub-lists)。
普通版
def quick_sort(list): less = [] pivotList = [] more = [] # 遞歸出口 if len(list) <= 1: return list else: # 將第一個值作爲基準 pivot = list[0] for i in list: # 將比急轉小的值放到less數列 if i < pivot: less.append(i) # 將比基準打的值放到more數列 elif i > pivot: more.append(i) # 將和基準相同的值保存在基準數列 else: pivotList.append(i) # 對less數列和more數列繼續進行排序 less = quick_sort(less) more = quick_sort(more) return less + pivotList + more
咳咳,下面這段代碼出自《Python cookbook 第二版》傳說中的三行實現python快速排序。
def qsort(arr): if len(arr) <= 1: return arr else: pivot = arr[0] return qsort([x for x in arr[1:] if x < pivot]) + \ [pivot] + \ qsort([x for x in arr[1:] if x >= pivot])
固然還有一行語法糖版本:
qs = lambda xs : ( (len(xs) <= 1 and [xs]) or [ qs( [x for x in xs[1:] if x < xs[0]] ) + [xs[0]] + qs( [x for x in xs[1:] if x >= xs[0]] ) ] )[0]
是否是感覺到了Python的魅力?
堆排序(Heapsort)是指利用堆這種數據結構所設計的一種排序算法。堆積是一個近似徹底二叉樹的結構,並同時知足堆積的性質:即子結點的鍵值或索引老是小於(或者大於)它的父節點。
def heap_sort(list): # 建立最大堆 for start in range((len(list) - 2) // 2, -1, -1): sift_down(list, start, len(list) - 1) # 堆排序 for end in range(len(list) - 1, 0, -1): list[0], list[end] = list[end], list[0] sift_down(list, 0, end - 1) return list # 最大堆調整 def sift_down(lst, start, end): root = start while True: child = 2 * root + 1 if child > end: break if child + 1 <= end and lst[child] < lst[child + 1]: child += 1 if lst[root] < lst[child]: lst[root], lst[child] = lst[child], lst[root] root = child else: break
當輸入的元素是n個0到k之間的整數時,它的運行時間是Θ(n + k)。計數排序不是比較排序,排序的速度快於任何比較排序算法。
因爲用來計數的數組C的長度取決於待排序數組中數據的範圍(等於待排序數組的最大值與最小值的差加上1),這使得計數排序對於數據範圍很大的數組,須要大量時間和內存。例如:計數排序是用來排序0到100之間的數字的最好的算法,可是它不適合按字母順序排序人名。可是,計數排序能夠用在基數排序算法中,可以更有效的排序數據範圍很大的數組。
def count_sort(list): min = 2147483647 max = 0 # 取得最大值和最小值 for x in list: if x < min: min = x if x > max: max = x # 建立數組C count = [0] * (max - min +1) for index in list: count[index - min] += 1 index = 0 # 填值 for a in range(max - min+1): for c in range(count[a]): list[index] = a + min index += 1 return list
None?
固然不會
天然就是系統自帶的
list.sort()
以上全部源代碼均在Github共享但願與你們共同進步!
知乎用戶:dhx1793516813、左鳶、靈劍
爲本文缺漏之處提出建議
EOF
轉載請註明出處: http://eindex.me/post/base-so...
訪問原文「 基本排序算法的Python實現」獲取最佳閱讀體驗並參與討論