一、冒泡排序
1、冒泡排序,从前往后,两两进行比较,最大的放在最后面
2、稳定
3、时间复杂度o(n^2) 最优是不排序o(n)
# 排序算法
# 1、冒泡排序,从前往后,两两进行比较,最大的放在最后面
# 2、稳定
# 3、时间复杂度o(n^2) 最优是不排序o(n)
def bubble(lst):
n = len(lst)
for i in range(n-1): # 只需要遍历前n-1个元素
for j in range(n-i-1): # 从0-n-1,从1-n-2
if lst[j] > lst[j+1]: # 这里i控制起始的位置,j控制两两比较移动的位置
lst[j], lst[j + 1] = lst[j+1], lst[j] # 如果出现前面的比后面大,就交换,继续到下一个遍历
return lst
lst = bubble([3,2,14,6])
print(lst)
二、选择排序
1、选择排序,从未排序的列表中选择最小的向已排序的列表中插入
从未排序序列中找到最小(大)的元素,放到序列起始位置,然后在剩下的元素中继续找,
依次类推,平均时间复杂度为 o(n^2)最坏时间复杂度相同
2、不稳定 5 8 5 2
# 选择排序
# 从未排序的列表中选择最小的向已排序的列表中插入
# 不稳定 5 8 5 2
def select(nums):
n = len(nums)
for i in range(n-1):
minindex = i
for j in range(i+1, n):
if nums[minindex] > nums[j]:
minindex = j
if i != minindex:
nums[minindex], nums[i] = nums[i], nums[minindex]
return nums
lst = select([2, 1, 5, 3, 6, 9, 4])
print(lst)
三、插入排序
1、插入排序,从未排序的列表中向已排序的列表中插入元素,确定当前索引j,然后与已排序的列表一一对比,最终交换使得变为排序好的列表
2、稳定的 [5, 5, 2]
# 插入排序
# 从未排序的列表中向已排序的列表中插入元素,确定当前索引j,然后与已排序的列表一一对比,最终交换使得变为排序好的列表
# 稳定 [5, 5, 2]
def insert(nums):
n = len(nums)
for i in range(1, n): # 从第二个开始遍历
j = i
while j > 0:
if nums[j] < nums[j-1]: # 如果后面的比前面的小
nums[j], nums[j-1] = nums[j-1], nums[j] # 交换
j -= 1
else: # 如果后面的比前面的大,直接退出循环
break
return nums
lst = insert([5, 5, 2])
print(lst)
# 插入排序
def maopao(lst):
n = len(lst)
for i in range(1, n):
j = i
for j in range(i, 0, -1): # 这里有繁琐遍历
if lst[j] < lst[j-1]:
lst[j], lst[j-1] = lst[j-1], lst[j]
else:
break # 退出当前循环
return lst
lst = maopao([4,3,1,7,9,2])
print(lst)
四、归并排序
自上而下分成小块,排序完成,自下而上的合并
稳定
# 归并排序
# 自上而下分成小块,排序完成,自下而上的合并
# 不稳定
def join(lst):
# 分一半 显示[3,6,2] 继续分[3] [6,2] 继续分 [3],[6] [2] 排序后[3] [2,6] 继续进行排序 [2,3,6]
n = len(lst)
if n <= 1:
return lst
mid = n//2
left = join(lst[:mid]) # 递归运行
right = join(lst[mid:])
leftpoint, rightpoint = 0, 0
ret = []
while leftpoint < len(left) and rightpoint < len(right):
if left[leftpoint] > right[rightpoint]:
ret.append(right[rightpoint])
rightpoint += 1
else:
ret.append(left[leftpoint])
leftpoint += 1
ret += left[leftpoint:]
ret += right[rightpoint:]
return ret # 这里每次递归都是返回一个ret,那么作为下次递归的结果,与中间的ret=[]不会互相干扰
lst = join([3,6,2,9,5,7])
print(lst)
五、快速排序
最优时间复杂度 o(nlogn)!!!
最坏时间复杂度 o(n^2)
稳定性:不稳定
def quick_sort(alist, first, last):
# 快速排序
if first >= last:
return
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 += 1
while low < high and alist[low] < mid_value:
low += 1
alist[high] = alist[low]
# high -= 1
# 从循环退出时,low = high
alist[low] = mid_value
# 包含等于情况尽量放在一边
# 对 low 左边的列表执行快速排序
quick_sort(alist, first, low - 1)
# 对 low 右边的列表执行快速排序
quick_sort(alist, low + 1, last)
if __name__ == '__main__':
li = [4,2,7,5,9,0]
print(li)
quick_sort(li, 0, len(li) - 1)
print(li)