標籤:排序演算法 演算法 python
聲明:本文涉及的所有排序演算法定義功能對輸入進行從小到大排序
符號解釋:
n:輸入資料個數
Θ(n):n的同階無窮大
一、選擇排序
def SelectSort(a): for i in range(0,len(a)-1): minIndex=i for j in range(i+1,len(a)): if a[j]<a[minIndex]: minIndex=j if minIndex !=i: temp=a[minIndex] a[minIndex]=a[i] a[i]=temp return aa=[2,5,3,8,6,1,4,9]SelectSort (a)print(a)
從前往後,依次選擇當前位置以後最小的數與當前位置交換
計算複雜度theta(n^2)
二、冒泡排序
def BubbleSort (a): k=len(a) for i in range(0,k-1): for j in range(k-1,i,-1): if a[j]<a[j-1]: a[j-1],a[j]=a[j],a[j-1] return aa=[2,5,3,8,6,7,1,4,9]BubbleSort (a)print(a)
從前往後,反覆交換相鄰的未按次序排列的元素
計算複雜度theta(n^2)
三、插入排序
def InsertSort(a): for j in range(1,len(a)): key=a[j] i=j-1 while(i>=0 and a[i]>key): a[i+1]=a[i] i=i-1 a[i+1]=keya=[2,5,3,8,6,1,4,9]InsertSort (a)print(a)
從前往後,講下一個資料插入到前面已經排好序的數組裡面
最好的情況:已經從小到大排好序,計算複雜度theta(n)
最壞的情況:輸入順序為從大到小,計算複雜度theta(n^2)
當資料量很大的時候,不必要一個一個往前找,可以根據二分發,減少計算量
四、歸併排序
def MergeSort(a): n=len(a) if n==1: return a mid=(n+1)//2 b=MergeSort(a[0:mid]) c=MergeSort(a[mid:n]) i=0 j=0 b.append(float("inf")) c.append(float("inf")) for k in range(0,n): if b[i]<c[j]: a[k]=b[i] i+=1 else: a[k]=c[j] j+=1 return aa=[2,5,3,8,6,7,1,4,9]MergeSort (a)print(a)
分治策略,先劃分子序列,後歸併排序
計算複雜度theta(nlog(n))
注意:非原址運算
五、堆排序
def HeapAdjust(lst,k,n): while(2*k+1<n): j=2*k+1 if j+1<n and lst[j]<lst[j+1]: j=j+1 if lst[j]>lst[k]: lst[k],lst[j]=lst[j],lst[k] k=j else: break return lstdef HeapSort(lst): n=len(lst) for i in range(n//2-1,-1,-1): lst=HeapAdjust(lst,i,n) for i in range(n-1,0,-1): lst[0],lst[i]=lst[i],lst[0] lst=HeapAdjust(lst,0,i) return lsta=[1,5,2,8,3,4,6,9,7]HeapSort(a)print(a)
代碼注釋:http://blog.csdn.net/zhangzhengyi03539/article/details/44889951
構建大根堆,然後堆頂元素與序列最後一個元素交換,序列長度減一,對堆頂元素構建大根堆
計算複雜度theta(nlogn)
我覺得這個演算法還有可能改進的地方,因為每次堆頂元素與最後一個元素交換,而最後一個元素是大根堆葉子上的元素,也就是在這條支路中最小的元素,這樣在重新對堆頂元素構建大根隊的過程中需要迭代好多步驟。
六、快速排序
例子一:
def QuickSort(a,start,end): key=a[start] i=start+1 j=end while i<j: while a[i]<=key and i<j: i+=1 while a[j]>key and j>i-1: j-=1 if i<j: a[i],a[j]=a[j],a[i] a[start],a[j]=a[j],a[start] if j-1>start: QuickSort(a,start,j-1) if j+1<end: QuickSort(a,j+1,end) return aa=[1,5,2,8,3,4,6,9,7]QuickSort(a,0,len(a)-1)print(a)
例子二:
def QuickSort(a,start,end): key=a[end] i=start-1 for j in range(start,end): if a[j]<key: i+=1 a[i],a[j]=a[j],a[i] a[i+1],a[end]=a[end],a[i+1] if i>start: QuickSort(a,start,i) if i+2<end: QuickSort(a,i+2,end) return aa=[1,5,2,8,3,4,6,9,7]QuickSort(a,0,len(a)-1)print(a)
代碼注釋http://blog.csdn.net/zhangzhengyi03539/article/details/41180337
分治策略,最好的情況當然是每次都是二分了
平均情況/期望情況:計算複雜度theta(nlogn)
最壞的情況:計算複雜度theta(n^2)
對於例子二,考慮這樣一種情況,輸入序列最後一個是最大的,然後對j迴圈的時候每次都要執行交換操作。還有就是快速排序的隨機化版本,每次從輸入中隨機挑選一個數與key所在的數交換,然後執行快速排序。
排序演算法總結(python)