一、插入排序:
工作原理: 通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到响应位置并插入。其中,未排序序列跟已排序序列都在同个列表中。
实现: 在从后面扫描过程中,需要反复把已排序元素逐步向后挪动,为最新元素提供插入空间
二、希尔排序:
工作原理: 希尔排序是插入排序的一种,也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是把记录按下标一定增量分组,对每组使用直接插入排序算法排序;随着增量逐量减少,每组包含的关键词越来越多,当增量减之1时,整个文件恰分成一组,算法便终止。
时间赋值度:
- 最优的复杂度:n的1.3次方
- 最坏复杂度:n的平方
for j in range(len(alist)//2, 0, -1): # 增量需要从len(alist)//2开始
i = j
while i < len(alist):
if alist[i-j] < alist[i]:
alist[i-j], alist[i] = alist[i], alist[i-j]
i += 1
三、选择排序
工作原理: 首先在未排序序列中找到最小(大)的元素,存放在排序序列的起始位置,然后,再从剩余未排序元素中寻找最小(大),然后放到已排序序列的末尾。依次类推,直到所有元素均排序完毕。
代码:
for number in range(len(alist) - 1)
min_number, i = number ,number
while i < len(alist):
if alist[i] < alist[min_number]:
min_number = i
else i += 1
alist[number], alist[min_number] = alist[min_number], alist[number]
四、冒泡排序
工作原理: 从第一个开始遍历,如果alist[i] > alist[i+1],就替换,然后移动,直到将列表中最大的数放到末尾,继续从第一个开始,依次比较,直到将未排序列表中最大的数放到次末尾,依次类推,直到所有元素排序完毕。
代码:
n = len(alist)
for gap in range(n-1):
count = 0 # 减少不必要的排序
for i in range(n-1-gap):
if alist[i] > alist[i+1]:
alist[i], alist[i+1] = alist[i+1], alist[i]
count += 1
if 0 == count:
return
五、快速排序
步骤:
- 从数列中挑出一个元素,称为“基数”
- 重新排序数列,所有元素比基数值小的摆放在基数前面,所有比基数值大的摆放在后面(相同的数可以放任何一变)。在这里分区结束之后,就基数就处于列表的中间。
- 递归地把小于基准值元素的子序列和大于基数值元素的子序列排序
代码:
def quick_sort(alsit, first, last):
"""快速排序"""
if len(alist)< 1:
return alist
mid_value = alist[first]
low = first
high = last
while low < high:
# high左移,相等的,也放在右边
while low < high and alist[high] >= mid_value:
high -= 1
alist[low] = alist[high]
# low右移, 想等的,放在右边
while low < high and alist[low] < mid_value:
low += 1
alist[high] = alist[low]
alist[low] = mid_value
# 列表切片,,是赋予新的列表,而不是原来的列表
quick_sort(alist, first, low-1)
quick_sort(alist, low+1, last)
时间复杂度:
- 最优时间复杂度:nlogn
- 最坏复杂度:n的平方
- 把列表拆分成1个,就相当于2的几次方大于len(list), 拆一次需要N步骤,所有时间复杂度nlogn
六、归并排序
工作原理: 拆分 + 排序合并
def merget_sort(alist):
"""归并排序"""
n = len(alist)
if n <= 11:
return alist
mid = n // 2
# left采用归并排序后形成的有序的新的列表
left_li = merge_sort(alist[:mid])
# right采用归并排序后形成的有序的新的列表
right_li = merge_sort(alist[mid:])
# 将俩个有序的子序列合并成一个新的整体
letf_pointer, right_pointer = 0, 0
result = []
while left_pointer < len(left_li) and right_pointer < len(right_li):
if left_li[left_pointer] < right_li[right_pointer]:
result.append(left_li[left_pointer])
left_pointer += 1
else:
result.append(right_li[right_pointer])
right_pointer += 1
result.extend(left_li[left_pointer:])
result.extend(right_li[right_pointer:])
return result