######## 基于比较的排序方法 ########
######### 1. Bubble Sort #########
def BubbleSort(a): #average:O(N^2), best:O(N)#
length = len(a)
flag = True #数组有序时,跳出循环、不再冒泡
for i in range(length-1): #length-1次
flag = False
for j in range(length-1-i):
if a[j] > a[j+1]:
flag = True
a[j],a[j+1] = a[j+1],a[j]
if not flag: break
return a
######### 2. Selection Sort #########
def SelectionSort(a): #O(N^2)
length = len(a)
for i in range(length-1):
min = i,a[i]
for j in range(i+1, length):
if a[j] < min[1]:
min = j,a[j]
a[i],a[min[0]] = a[min[0]],a[i]
return a
######### 3. Insertion Sort #########
def InsertionSort(a): #O(N^2)
length = len(a)
for i in range(1,length):
for j in range(i-1,-1,-1):
if a[j]>a[j+1]: #有点像反过来的冒泡排序
a[j+1],a[j]=a[j],a[j+1]
return a
######### 4. Merge Sort #########
def MergeSort(a): #O(NlogN)
if len(a) <= 1: return a
mid = len(a)//2
left = MergeSort(a[:mid]) #必须是mid,不能是mid+1,否则len(a)=2时会陷入死循环
right = MergeSort(a[mid:])
return Merge(left, right)
def Merge(a,b):
res = []
p1, p2 = 0,0
m1,m2 = len(a),len(b)
while p1<m1 and p2<m2:
if a[p1] <= b[p2]:
res.append(a[p1])
p1 += 1
else:
res.append(b[p2])
p2 += 1
res.extend(a[p1:])
res.extend(b[p2:])
return res
######### 5. Quick Sort #########
def QuickSort(a,start=0,end=None): #average/best:O(NlogN), worst:O(N^2)
end = len(a) if end is None else end
if start >= end: return
newPivot = partition(a,start,end)
QuickSort(a,start,newPivot)
QuickSort(a,newPivot+1,end)
return a
def partition(a,start=0,end=None): #[start,end),返回排序后pivot的位置,且pivot左小右大
end = len(a) if end is None else end
pivot = a[start]
partition = start + 1
for i in range(start+1,end):
if a[i]<pivot:
a[i],a[partition] = a[partition],a[i]
partition += 1
a[partition-1],a[start] = a[start], a[partition-1]
return partition-1
######### 6. Random Quick Sort #########
import random
def RandomQuickSort(a,start=0,end=None): #[start,end)
end = len(a) if end is None else end
if start >= end: return
newPivot = random_partition(a,start,end)
RandomQuickSort(a,start,newPivot)
RandomQuickSort(a,newPivot+1,end)
return a
def random_partition(a,start=0,end=None): #[start,end),返回排序后pivot的位置,且pivot左小右大
end = len(a) if end is None else end
##小区别##
newstart = random.randint(start,end-1)
a[start], a[newstart] = a[newstart], a[start]
##
pivot = a[start]
partition = start + 1
for i in range(start+1,end):
if a[i]<pivot:
a[i],a[partition] = a[partition],a[i]
partition += 1
a[partition-1],a[start] = a[start], a[partition-1]
return partition-1
######## 不是基于比较的排序方法 ########
######### 7. Counting Sort #########
def CountingSort(a): #O(N),数据分布不能太分散
mini,maxi = min(a),max(a)
count = maxi - mini + 1
counter = [0]*count
for i in a:
counter[i-mini] += 1
res = []
for i in range(count):
res.extend([mini+i]*counter[i])
return res
######### 8. Radix Sort #########
def RadixSort(a): #O(d(n+r)),d:digit,r:radix. => O(N)
maxi = max(a)
digits = len(str(maxi)) #记录最大值的位数,即为接下来的排序轮数
for digit in range(digits):
bucket = [[] for _ in range(10)] #记录0~9的10个桶
for i in a:
temp = digitK(i,digit)
bucket[temp].append(i)
a = [j for i in bucket for j in i]
return a
def digitK(num,k):
if k==0: return num%10
return digitK(num//10, k-1)
排序算法的python实现(冒泡、选择、插入、归并、快排、计数、基数)
于 2022-03-28 12:58:20 首次发布