主要包括(选择,冒泡,插入,归并,非递归归并,快排,双路快排,三路快排,非递归快排,堆排)
算法复杂度以及内存分析
算法 | 平均复杂度 | 最坏情况 | 原地排序 | 额外空间 | 是否稳定 |
---|---|---|---|---|---|
选择排序 | o( n 2 n^{2} n2) | o( n 2 n^{2} n2) | 是 | o(1) | 是 |
冒泡排序 | o( n 2 n^{2} n2) | o( n 2 n^{2} n2) | 是 | o(1) | 是 |
插入排序 | o( n 2 n^{2} n2) | o( n 2 n^{2} n2) | 是 | o(1) | 是 |
归并排序 | o( n l o g n nlogn nlogn) | o( n l o g n nlogn nlogn) | 否 | o(n) | 是 |
快速排序 | o( n l o g n nlogn nlogn) | o( n 2 n^{2} n2) | 是 | o(logn) | 否 |
堆排序 | o( n l o g n nlogn nlogn) | o( n l o g n nlogn nlogn) | 是 | o(1) | 否 |
值得注意的是:
插入排序对于近乎有序数组性能比较好,最好的情况达到o(n)。
快排是几种nlogn级别里面最快的算法
当数组元素有很多重复的时,使用三路快排比较有优势
代码
1. 选择排序
#选择排序
def SelectionSort(arr):
for i in range(len(arr)-1):
min_index = i
for j in range(i+1, len(arr)):
if arr[j]<arr[min_index]:
min_index = j
arr[min_index],arr[i] = arr[i], arr[min_index]
2 . 冒泡排序
#冒泡排序
def BubbleSort(arr):
for i in range(len(arr)-1):
for j in range(len(arr)-i-1):
if arr[j]>arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
3. 插入排序
def InsertionSort(arr):
for i in range(1,len(arr)):
j = i
e = arr[i]
while j>0:
if e <arr[j-1]:
arr[j] = arr[j-1]
j = j - 1
else:
break
arr[j] = e
4.归并排序
def MergeSort(arr):
mergesort(arr, 0, len(arr)-1)
def mergesort(arr, l, r):
if l>=r:
return
mid = int((l+r)/2)
mergesort(arr, l, mid)
mergesort(arr, mid+1, r)
merge(arr, l, mid, r)
def merge(arr, l, mid, r):
aux = arr[l:r+1]
i = l
j = mid+1
for k in range(l,r+1):
if i>mid:
arr[k] = aux[j-l]
j = j+1
elif j>r:
arr[k] = aux[i-l]
i = i+1
elif aux[i-l]>aux[j-l]:
arr[k] = aux[j-l]
j = j+1
else:
arr[k] = aux[i-l]
i = i+1
5.非递归归并
def MergeSortBottomUp(arr):
n = len(arr)
s = 1
while s<=n:
i = 0
while i+s < n:
merge(arr, i, i+s-1, min(i+2*s-1,n-1))
i = i+2*s
s = s+s
6.快速排序
def QuickSort(arr):
quicksort(arr, 0, len(arr)-1)
def quicksort(arr, l, r):
if l>=r:
return
p = partition(arr, l, r)
quicksort(arr, l , p)
quicksort(arr, p+1, r)
def partition(arr, l, r):
v = arr[l]
j = l
for i in range(l+1,r+1):
if arr[i]<v:
j = j+1
arr[i], arr[j] = arr[j], arr[i]
arr[l], arr[j] = arr[j], arr[l]
return j
7.双路快排
def QuickSortTwoWays(arr):
quicksortTwoWays(arr, 0 ,len(arr)-1)
def quicksortTwoWays(arr, l, r):
if l>= r:
return
p = partitionTwoWays(arr, l, r)
quicksortTwoWays(arr, l, p)
quicksortTwoWays(arr, p+1, r)
def partitionTwoWays(arr, l, r):
v = arr[l]
i = l+1
j = r
while(True):
while i<r and arr[i]<v:
i = i+1
while j>l and arr[j]>v:
j = j -1
if i>j:
break
arr[i],arr[j] = arr[j], arr[i]
i = i+1
j = j-1
arr[l], arr[j] = arr[j], arr[l]
return j
8.三路快排
def QuickSortThreeWays(arr):
quicksortThreeWays(arr, 0, len(arr)-1)
def quicksortThreeWays(arr, l, r):
if l>=r:
return
v = arr[l]
it = l
gt = r+1
i = l+1
while i<gt:
if arr[i]<v:
it += 1
arr[i], arr[it] = arr[it], arr[i]
i += 1
elif arr[i]>v:
gt -= 1
arr[i], arr[gt] = arr[gt], arr[i]
else:
i = i+1
arr[l], arr[it] = arr[it], arr[l]
quicksortThreeWays(arr, l, it-1)
quicksortThreeWays(arr, gt, r)
9.非递归快排
def QuickSortNR(arr):
l = 0
r = len(arr) - 1
s = []
s.append(r)
s.append(l)
while s:
l = s.pop()
r = s.pop()
if l>=r:
continue
p = partition(arr, l, r)
s.append(p)
s.append(l)
s.append(r)
s.append(p+1)
10.原地堆排
def HeapifySort(arr):
for i in range(int((len(arr)-2)/2),-1,-1):
ShiftDown(arr, len(arr)-1, i)
for i in range(len(arr)-1, 0, -1):
arr[0], arr[i] = arr[i] , arr[0]
ShiftDown(arr, i-1, 0)
def ShiftDown(arr, n, i):
k = i
while 2*k+1<=n:
index = 2*k+1
if 2*k+2 <=n and arr[2*k+2]>arr[2*k+1]:
index = 2*k+2
if arr[k]>= arr[index]:
break
arr[k], arr[index] = arr[index], arr[k]
k = index