Algorithms -sort
程序员文章站
2022-03-14 13:38:38
...
1.选择排序
从数组中选择最小元素,将它与数组的第一个元素交换位置。再从数组剩下的元素中选择出最小的元素,将它与数组的第二个元素交换位置。不断进行这样的操作,直到将整个数组排序。
选择排序需要 ~N2/2 次比较和 ~N 次交换,它的运行时间与输入无关,这个特点使得它对一个已经排序的数组也需要这么多的比较和交换操作。
def selection_sort(collection
):
n = len(collection)
for i in range(n-1):
least = i
for j in range(i+1, n):
if collection[j] < collection[i]:
least = j
collection[i], collection[least] = collection[least],collection[i]
return collection
2.冒泡排序
从左到右不断交换相邻逆序的元素,在一轮的循环之后,可以让未排序的最大元素上浮到右侧。
在一轮循环中,如果没有发生交换,那么说明数组已经是有序的,此时可以直接退出。
def bubble_sort(collection
):
n = len(collection)
for i in range(n-1):
swapped = False
for j in range(n-i-1):
if collection[j] > collection[j+1]:
swapped = True
collection[j], collection[j+1] = collection[j+1],collection[j]
if not swapped:
break
return collection
3.插入排序
每次都将当前元素插入到左侧已经排序的数组中,使得插入之后左侧数组依然有序。
对于数组 {3, 5, 2, 4, 1},它具有以下逆序:(3, 2), (3, 1), (5, 2), (5, 4), (5, 1), (2, 1), (4, 1),插入排序每次只能交换相邻元素,令逆序数量减少 1,因此插入排序需要交换的次数为逆序数量。
插入排序的时间复杂度取决于数组的初始顺序,如果数组已经部分有序了,那么逆序较少,需要的交换次数也就较少,时间复杂度较低。
平均情况下插入排序需要 ~N2/4 比较以及 ~N2/4 次交换; 最坏的情况下需要 ~N2/2 比较以及 ~N2/2 次交换,最坏的情况是数组是倒序的; 最好的情况下需要 N-1 次比较和 0 次交换,最好的情况就是数组已经有序了。
def insertion_sort(collection
):
n = len(collection)
for i in range(1, n):
j = i-1
v = collection[i]
while j>=0 and collection[j]>v:
collection[j+1] = collection[j]
j = j-1
collection[j+1] = v
return collection
4.归并排序
对一个需要排序的数组,先把它一分为二,对每个子数组递归排序,然后把这两个排好序的子数组合并为一个有序的数组
def merge_sort(collection
):
def merge(left, right):
result = []
while left and right:
result.append((left if left[0] <= right[0] else right).pop(0))
return result+left+right
if len(collection)>1:
mid = len(collection)//2
left = collection[:mid]
right = collection[mid:]
return merge(merge_sort(left), merge_sort(right))
return collection
下一篇: OpenJDK多语言虚拟机项目介绍