一、性质
- 稳定性:稳定的算法能够维持序列中所有排序码相同记录的相对位置。
- 适应性:对接近有序的序列工作更快。
二、插入排序
- 不断的把元素插入到已经排好序的序列中。
def insert_sort(array):
for i in range(1, len(array)):
x = array[i]
j = i
while j > 0 and array[j-1] > x:
array[j] = array[j-1]
j -= 1
array[j] = x
- 空间复杂度O(1)
- 平均时间复杂度O(n2)
- 最好情况:已经有序O(n)
- 最坏情况:逆排序O(n2)
- 适应性:有
- 稳定性:稳定。因为遇到和x一样大的,就不再移动,能保持顺序
稳定性是针对实现的,如果把上述改为array[j-1] >= x,则不稳定。
三、选择排序
- 每次选择最小的元素,放在已经排好序的序列后面。
def select_sort(array):
for i in range(len(array)-1):
k = i
for j in range(i, len(array)):
if array[j] < array[k]:
k = j
if i != k:
array[i], array[k] = array[k], array[I]
- 空间复杂度O(1)
- 平均时间复杂度O(n2)
- 最好情况:已经有序O(n2)
- 最坏情况:逆排序O(n2)
- 适应性:无
- 稳定性:无
四、堆排序
- 首先构建小顶堆
- 每次弹出的就是最小值,希望能不利用其他空间,每次弹出就后面就会空出来一个位置,正好存放弹出的元素,不过这样的到的结果是从大到小,可以反转,或者直接构建大顶堆。
def heap_sort(elems):
def siftdown(elems, e, begin, end):
i ,j = begin, begin * 2 + 1
while j < end:
if j + 1 < end and elems[j+1] < elems[j]:
j += 1
if e < elems[j]:
break
elems[i] = elems[j]
i, j = j, 2 * j + 1
elems[i] = e
end = len(elems)
# buid heap O(n)
for i in range(end//2, -1, -1):
siftdown(elems, elems[i], i, end)
# O(nlogn)
for i in range((end - 1), 0, -1):
e = elems[i]
elems[i] = elems[0]
siftdown(elems, e, 0, i)
- 空间复杂度O(1)
- 平均时间复杂度O(nlogn)
- 最好情况:已经有序O(nlogn)
- 最坏情况:逆排序O(n2)
- 适应性:无
- 稳定性:无
五、冒泡排序
反复比较相邻元素,发现相邻的逆序对就交换。
def bubbleSort(array):
for i in range(len(array)):
found = False
for j in range(len(array) - i - 1):
if array[j] > array[j+1]:
found = True
array[j], array[j+1] = array[j+1], array[j]
if not found:
break
- 空间复杂度O(1)
- 平均时间复杂度O(n2)
- 最好情况:已经有序O(n)
- 最坏情况:逆排序O(n2)
- 适应性:有
- 稳定性:有
六、快排
按照某种标准把序列划分为大的和小的,并递归执行。
递归实现
def quickSort(array, l, r):
if l < r:
mid = partition(array, l, r)
quickSort(array, l, mid-1)
quickSort(array, mid+1, r)
def partition(array, l, r):
i = l - 1
x = array[r]
for j in range(l, r):
if array[j] >= x:
i += 1
array[i], array[j] = array[j], array[i]
array[i+1], array[r] = array[r], array[i+1]
return i+1
非递归实现
def quickSort(Array):
l, r = 0, len(Array)-1
stack = [(l, r)]
while stack:
left, right = stack.pop(0)
x = Array[right]
i = left - 1
for j in range(left, right):
if Array[j] <= x:
i += 1
Array[j], Array[i] = Array[i], Array[j]
Array[i+1], Array[right] = Array[right], Array[i+1]
mid = i + 1
if left < mid - 1:
stack.append((left, mid - 1))
if mid + 1 < right:
stack.append((mid + 1, right))
- 空间复杂度最坏O(n)
- 平均时间复杂度O(nlogn)
- 最坏情况:逆排序O(n2)
- 适应性:无
- 稳定性:无
七、归并排序
def mergeSort(array):
if len(array) < 2:
return array
mid = len(array) >> 1
left = mergeSort(array[:mid])
right = mergeSort(array[mid:])
return merge(left, right)
def merge(a1, a2):
m, n = len(a1), len(a2)
i = j = 0
a = []
while i < m and j < n:
if a1[i] <= a2[j]:
a.append(a1[i])
i += 1
else:
a.append(a2[j])
j += 1
while i < m:
a.append(a1[i])
i += 1
while j < n:
a.append(a2[j])
j += 1
return a
- 空间复杂度O(n)
- 平均时间复杂度O(nlogn)
- 适应性:无
- 稳定性:有