开始系统学习算法啦!为后面力扣和蓝桥杯的刷题做准备!这个专栏将记录自己学习算法是的笔记,包括概念,算法运行过程,以及代码实现,希望能给大家带来帮助,感兴趣的小伙伴欢迎评论区留言或者私信博主哦!今天更新的是《03_1排序算法:冒泡排序、选择排序、插入排序》
目录
冒泡排序概念
运作过程
算法分析
代码实现
选择排序概念
排序过程
时间复杂度
代码实现
插入排序概念
算法过程
时间复杂度
代码实现
总结
冒泡排序(Bubble Sort)是一种简单的排序算法。它重复的遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作室重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小(越大)的元素会慢慢“浮到”数列的顶端。
时间复杂度:
def bubble_sort_1(alist):
"""
两个for循环嵌套
以 alist = [1,3,2,5,7,6,4]为例
第一次需要遍历到索引6,第二次5,直到索引0
:param alist:
:return:alist:list
"""
for k in range(0,len(alist)-1):
for i in range(0,len(alist)-1-k):
if alist[i] > alist[i+1]:
alist[i],alist[i+1] = alist[i+1],alist[i] # 实现升序排列
return alist
def bubble_sort_2(alist):
"""
while循环+for循环嵌套
以 alist = [1,3,2,5,7,6,4]为例
主要是k的值的变化
:param alist:
:return:alist:list
"""
k = 0
while k != len(alist)-1:
k += 1
for i in range(0,len(alist)-k):
if alist[i] > alist[i+1]:
alist[i],alist[i+1] = alist[i+1],alist[i] # 实现升序排列
return alist
def bubble_sort_3(alist):
"""
while循环+for循环嵌套
以 alist = [1,3,2,5,7,6,4]为例
如果遍历的时候没有发现要交换的,则这个列表已经是一个排好序的,则直接break
:param alist:
:return:alist:list
"""
for k in range(0,len(alist)-1):
count = 0
for i in range(0,len(alist)-1-k):
if alist[i] > alist[i+1]:
count += 1
alist[i],alist[i+1] = alist[i+1],alist[i] # 实现升序排列
if count == 0:
break
return alist
在这个优化里面只有当遍历完之后发现所有的都不需要操作的时候才会break,所以它的最乐观的时间复杂度还是O(n),最差的时间复杂度还是O(n^2),只在特定的情况下才会有优化的效果。我也尝试着用time模块的time.time()函数来获取程序运行的时间 ,但是程序运行的时间太短了,最终都显示0.0,我也懒得去增大列表的长度了(狗头)。
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下:
总结:先找出最大(最小)的元素,放在第一位或者最后一位。以找出最大的放在第一位为例,先找出最大的放在第一位,再在剩下的元素找出最大的元素,放在第二位,依次进行,直到遍历到最后一个元素,排序结束。选择选的就是最大或者最小的的,相当于挑高个,挑完最高的,再挑次高的,直到结束。
最优时间复杂度:O(n^2)
最坏时间复杂度:O(n^2)
稳定性:不稳定(考虑升序每次选择最大的情况)
def selection_sort(alist):
"""
:param alist:
:return: alist
思想就是不断找出最小的放在最前面
以alist = [10,1,3,2,5,7,6,4]为例,n=8
第一次是把1放在最前面
"""
n = len(alist) # 8
for i in range(n): # 0-7
# 下面一段代码是为了找到最小值
min_index = i
for j in range(i,n): #0-7
if alist[min_index] > alist[j]:
min_index = j
# 下面一段代码是为了交换最小值
if min_index != i:
alist[i],alist[min_index] = alist[min_index],alist[i]
return alist
程序可以看成两段,一段是找到剩下里面最小的元素,一段是交换最小值,这两步就可以完成排序,时间复杂度为O(n^2),注意写代码的时候,这两段要分开写,思路更加清晰一些,注意索引的值,可以代入最小时和最大时去检验,这样可以有效避免索引出错。
插入排序(Insertion Sort)是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应的位置并插入。插入排序在实现上,在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
def insert_sort(alist):
"""
:param alist:
:return: alist.sort
插入排序首先需要认定一个基准,一般认为是第一个
以alist = [10,1,3,2,5,7,6,4]为例,首先是1和10比较,需要交换,此时i=0,递减变为-1退出while循环
列表变为alist = [1,10,3,2,5,7,6,4],首先是3和10比较,需要交换,再和1比较,不需要交换,直到i递减到比0小,退出循环
列表的每一个元素都要这么操作,所以外层还要嵌套一个for循环去便利每一个元素
"""
for i in range(1,len(alist)):
while i > 0:
if alist[i-1] > alist[i]:
alist[i-1],alist[i] = alist[i],alist[i-1]
else:
break
i -= 1
return alist
比较一下排序:
从算法实现上来分别比较: