1、插入排序
工作原理:通过构建有序序列,对于未排序数据,在已排序序列中,从后向前扫描,找到相应位置并插入。
插入排序是最重要的简单排序方法,原因:
- 实现简单
- 自然的稳定性和适应性
def insert_sort(L):
for i in range(1, len(L)):
# 从第i个元素开始向前比较,如果小于前一个元素,交换位置
for j in range(i, 0, -1):
if L[j] < L[j-1]:
L[j], L[j-1] = L[j-1], L[j]
return L
2、选择排序
工作原理:在未排序序列中找到最小元素,放到排序序列的起始位置,然后再从剩余未排序元素中继续寻找最小元素,放到已排序序列的末尾。
选择排序比较低效,因为每次选择一个元素,都是从头开始做一遍完全的比较,在整个排序中做了很多重复的工作。
def select_sort(L):
for i in range(len(L)-1):
k = i
for j in range(i, len(L)): # k是已知最小元素的位置
if L[j] < L[k]:
k = j
if i != k: # L[k]是确定的最小元素,检查是否需要交换
L[i], L[k] = L[k], L[i]
return L
3、冒泡排序
冒泡排序是一种典型的通过交换元素消除逆序实现排序的方法,基本操作是反复比较和交换。
def bubble_sort(L):
for i in range(len(L)):
for j in range(1, len(L)):
if L[j-1] > L[j]:
L[j-1], L[j] = L[j], L[j-1]
return L
改进版本:
增加了一个Nfound来标记是否存在逆序,如果不存在立即结束循环,可能提高效率
def bubble_sort(L):
for i in range(len(L)):
Nfound = True
for j in range(1, len(L)):
if L[j-1] > L[j]:
L[j], L[j-1] = L[j-1], L[j]
Nfound = False
if Nfound:
break
return L
4、快速排序
快速排序是一种著名的排序算法,采用了递归方式,是实践中平均速度最快的算法之一。
def quick_sort(L, l, r):
# l即left,左索引,r即right,右索引
if l >= r:
return
i = l
j = r
pivot = L[i]
# while将大于中枢值pivot的元素放在其右边,小于其的放在左边
while i < j:
while i < j and L[j] >= pivot:
j -= 1
if i < j:
L[i] = L[j]
i += 1
while i < j and L[i] <= pivot:
i += 1
if i < j:
L[j] = L[i]
L[i] = pivot
# 划分的区域继续进行此逻辑,直到所有的区域i=j
quick_sort(L, l, i-1)
quick_sort(L, i+1, r)
return L
5、希尔排序
希尔排序是直接插入排序算法的一种更高效的改进版本,原理是不断将序列划切分,直到步长为1时使用简单的插入排序。
def shell_sort(L):
n = len(L)
step = int(n/2)
while step > 0:
for i in range(step, n):
j = i
while j >= step and L[j - step] > L[j]:
L[j - step], L[j] = L[j], L[j - step]
j -= step
step = int(step/2)
return L
6、并归排序
归并排序的思想就是先递归分解数组,再合并数组。将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,谁小就先取谁,取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可。
def merge_sort(L):
if len(L) <= 1:
return L
# 二分分解
num = int(len(L) / 2)
left = merge_sort(L[:num])
right = merge_sort(L[num:])
# 合并
return merge(left, right)
def merge(left, right):
"""合并操作,将两个有序数组left[]和right[]合并成一个大的有序数组"""
# left与right的下标指针
l, r = 0, 0
result = []
while l < len(left) and r < len(right):
if left[l] < right[r]:
result.append(left[l])
l += 1
else:
result.append(right[r])
r += 1
result += left[l:]
result += right[r:]
return result