引言
排序是数据处理中十分常见且核心的操作,虽说实际项目开发中很小几率会需要我们手动实现,各种集成的api已经帮我们省略了思考如何构建排序的时间,但如果我们从原理上出发,了解它们的实现机制,对我们学习算法还是十分有好处的。
排序分类
八大排序算法均属于内部排序。如果按照策略来分类,大致可分为:交换排序、插入排序、选择排序、归并排序和基数排序。如下图所示:
下面我们就来介绍一些关于排序算法的基础练习。
冒泡排序
我们可以由上图知道,冒泡排序是一种交换排序。那么什么又是交换排序呢?可以从字面意思上分析,两两比较待排序的关键字,并交换不满足次序要求的那对数,直到整个表都满足次序要求为止。而冒泡名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端,故名冒泡排序。
我们可以看下图,以数组为[29,10,14,37,25,18,30]为例:
def BubbleSort(input_list):
if len(input_list) <= 1:
return []
for i in range(len(input_list) - 1):
print("第%d轮排序:" % (i + 1))
for j in range(len(input_list) - 1):
if input_list[j + 1] < input_list[j]:
input_list[j],input_list[j+1] = input_list[j+1], input_list[j]
print(input_list)
return input_list
if __name__ == "__main__":
input_list = [29, 10, 14, 37, 25, 18, 30]
print("排序前:", input_list)
sorted_list = BubbleSort(input_list)
print("排序后:", sorted_list)
"""
排序前: [29, 10, 14, 37, 25, 18, 30]
第1轮排序:
[10, 29, 14, 37, 25, 18, 30]
[10, 14, 29, 37, 25, 18, 30]
[10, 14, 29, 37, 25, 18, 30]
[10, 14, 29, 25, 37, 18, 30]
[10, 14, 29, 25, 18, 37, 30]
[10, 14, 29, 25, 18, 30, 37]
第2轮排序:
[10, 14, 29, 25, 18, 30, 37]
[10, 14, 29, 25, 18, 30, 37]
[10, 14, 25, 29, 18, 30, 37]
[10, 14, 25, 18, 29, 30, 37]
[10, 14, 25, 18, 29, 30, 37]
[10, 14, 25, 18, 29, 30, 37]
......
排序后: [10, 14, 18, 25, 29, 30, 37]
"""
选择排序
每趟从待排序的记录中选出关键字最小的记录,顺序放在已排序的记录序列末尾,直到全部排序结束为止。
它的大致思想是:
- 从待排序序列中,找到关键字最小的元素;
- 如果最小元素不是待排序序列的第一个元素,将其和第一个元素互换;
- 从余下的 N - 1 个元素中,找出关键字最小的元素,重复(1)、(2)步,直到排序结束。
我们还是以[29, 10, 14, 37, 25, 18, 30]为例:
def SelectSort(input_list):
n = len(input_list)
if len(input_list) <= 1:
return []
for i in range(n - 1):
# 对第i个位置进行选择,选择最小第数放在第i位
min_index = i
for j in range(i + 1, n):
# 第i位和第j位进行比较,大的放后是升序,反之降序
# if input_list[i] > input_list[j]:
# input_list[i],input_list[j] = input_list[j],input_list[i]
if input_list[min_index] > input_list[j]:
min_index = j
if min_index != i:
input_list[min_index], input_list[i] = input_list[i], input_list[min_index]
return input_list
if __name__ == "__main__":
input_list = [29, 10, 14, 37, 25, 18, 30]
print("排序前:", input_list)
sorted_list = SelectSort(input_list)
print("排序后:", sorted_list)
"""
排序前: [6, 4, 8, 9, 2, 3, 1]
排序后: [1, 2, 3, 4, 6, 8, 9]
"""
快速排序
快速排序的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分:分割点左边都是比它小的数,右边都是比它大的数。
然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
def QuickSort(input_list, left, right):
def division(input_list, left, right):
base = input_list[left]
while left < right:
while left < right and input_list[right] >= base:
right -= 1
input_list[left] = input_list[right]
while left < right and input_list[left] <= base:
left += 1
input_list[right] = input_list[left]
input_list[left] = base
return left
if left < right:
base_index = division(input_list, left, right)
QuickSort(input_list, left, base_index - 1)
QuickSort(input_list, base_index + 1, right)
if __name__ == '__main__':
input_list = [6, 4, 8, 9, 2, 3, 1]
print('排序前:', input_list)
QuickSort(input_list, 0, len(input_list) - 1)
print('排序后:', input_list)
"""
"""
归并排序
def merge(left_list, right_list):
new_list = []
l_index, r_index = 0, 0
while l_index < len(left_list) and r_index < len(right_list):
# if l_index >= len(left_list) or r_index >= len(right_list):
# break
if left_list[l_index] < right_list[r_index]:
new_list.append(left_list[l_index])
l_index += 1
else:
new_list.append(right_list[r_index])
r_index += 1
new_list += left_list[l_index:]
new_list += right_list[r_index:]
return new_list
def merge_sort(alist):
if len(alist) == 1:
return alist
n = len(alist)
left_list = merge_sort(alist[:n//2])
right_list = merge_sort(alist[n//2:])
return merge(left_list, right_list)
print(merge_sort(l))
总结
参考与推荐:
1.
2.