本文不详细讲解排序原理,用 python 实现冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序。
冒泡排序
从第一个元素开始向倒数第二个元素,与后一个元素比较,如果该元素大于后一个元素,则交换,最大的元素将会被放在最后一个位置。再从第一个元素开始向倒数第三个元素,同样比较交换,次大的元素会被放在倒数第二个位置。依此类推,越大的元素越会被放在后面。
def bubble(list):
n = len(list)
for i in range(n - 1):
change = False
for j in range(n - 1 - i):
if list[j] > list[j + 1]:
list[j], list[j + 1] = list[j + 1], list[j]
change = True
if not change:
break
选择排序
选择序列中最小的元素放在第一个。除第一个以外,选择最小的元素放在第二个位置上。以此类推。
def select(list):
n = len(list)
for i in range(n - 1):
min_idx = i
# 找到最小值
for j in range(i + 1, n):
if list[j] < list[min_idx]:
min_idx = j
# 插入
list[i], list[min_idx] = list[min_idx], list[i]
插入排序
插入排序假设列表前一段的元素已经是有序的,从后面无序的序列中以此选择元素,插入到前面的有序序列中。在一开始,假设有序部分只有第一个元素。
def insert(list):
n = len(list)
for i in range(0, n):
j = i
while j > 0:
if list[j] < list[j - 1]:
list[j], list[j - 1] = list[j - 1], list[j]
j -= 1
else:
break
希尔排序
希尔排序把一整个无序序列分成若干个无序序列。假设间隔为 3,则 1、4、7 为一个无序序列,2、5、8 为一个无序序列, 3、6、9为另一个无序序列。针对每个小无序序列做插入排序。再把间隔缩小为 2,则针对每个小无序序列做插入排序。直至间隔缩小为 1。希尔排序最核心的地方还是插入排序。
def shell(list):
n = len(list)
gap = n // 2
while gap >= 1:
for j in range(gap, n):
i = j
while i > 0:
if list[i] < list[i - gap]:
list[i], list[i - gap] = list[i - gap], list[i]
i -= gap
else:
break
gap //= 2
快速排序
找到一个基准数,把比他小的数放在左侧,把比他大的数放在右侧,这样这个基准数就能放在正确的位置上。但它左侧的数和右侧的数都是乱序的,再分别对他们进行快速排序。以此类推,所有的数都能放在正确的位置上。
def quick(list, first, last):
if first >= last:
return
mid = list[first]
low = first
high = last
while low < high:
while low < high and list[high] >= mid:
high -= 1
list[low] = list[high]
while low < high and list[low] < mid:
low += 1
list[high] = list[low]
list[low] = mid
quick(list, first, low-1)
quick(list, low+1, last)
归并排序
归并算法把一整个序列分为前、后两个子序列,每个子序列又可分为前、后两个子序列,以此类推,直至每个子序列只有一个元素。当子序列只有一个元素时,则为有序的,两个有序的子序列合并为一个较大的子序列,以此类推,前、后两个有序的子序列,可以合并为一整个有序的序列。
def merge(list):
n = len(list)
if n <= 1:
return list
mid = n // 2
left = merge(list[: mid])
right = merge(list[mid:])
p, q = 0, 0
result = []
while p < len(left) and q < len(right):
if left[p] < right[q]:
result.append(left[p])
p += 1
else:
result.append(right[q])
q += 1
result += left[p:]
result += right[q:]
return result
测试
在 mian
函数里测试上面的排序算法。
if __name__ == "__main__":
list = [5, 1, 3, 7, 2, 6, 4, 9, 10, 8]
bubble(list)
print(list)
list = [5, 1, 3, 7, 2, 6, 4, 9, 10, 8]
select(list)
print(list)
list = [5, 1, 3, 7, 2, 6, 4, 9, 10, 8]
insert(list)
print(list)
list = [5, 1, 3, 7, 2, 6, 4, 9, 10, 8]
shell(list)
print(list)
list = [5, 1, 3, 7, 2, 6, 4, 9, 10, 8]
quick(list, 0, len(list)-1)
print(list)
list = [5, 1, 3, 7, 2, 6, 4, 9, 10, 8]
result = merge(list)
print(result)