基础排序算法
冒泡排序
思想就是将相邻元素两两比较,当一个元素大于右侧相邻元素时,交换他们的位置,小于右侧元素时,位置不变,最终序列中的最大元素,像气泡一样,到了最右侧。
这时冒泡排序第一轮结束,数列最右侧元素9的位置可认为是一个有序区,有序区目前有一个元素.
第二轮排序结束后,数列右侧的有序区有了两个元素.
由于该排序算法每一轮都要遍历所有元素,平均时间复杂度为O(n*n)
python
def bubble_sort(li):
for i in range(len(li)-1): # 第i趟
for j in range(len(li)-i-1):
if li[j]>li[j+1]: # 降序就改一下符号
li[j],li[j+1]=li[j+1],li[j]
li=[random.randint(1,100) for i in range(20)]
bubble_sort(li)
print(li)
如果在某一趟排序中列表没有发生变化,认为已经排好序,这时如果for循环遍历就极大浪费时间,我们可以加每一趟遍历前加一个标志位,在交换元素的代码处加一个修改标志位,这样就可以避免最坏情况出现.
python
def bubble_sort(li):
for i in range(len(li)-1):
exchange=False
for j in range(len(li)-i-1):
if li[j]>li[j+1]:
li[j],li[j+1]=li[j+1],li[j]
exchange=True
print(li) # 看每一趟的变化
if not exchange:
return
选择排序
基础思想为将列表中最小元素依次遍历筛选出来,最终得到一个有序列表
python
def select_sort_simple(li):
li_new=[]
for i in range(len(li)): # 一共需要拿i次
min_val=min(li)
li_new.append(min_val)
li.remove(min_val)
return li_new
这个算法虽然简单但是浪费内存,我们可以在列表内部遍历,找到最小元素后与第一个元素交换位置,左侧有序区就有了第一个元素.
python
def select_sort(li):
for i in range(len(li)-1): # i趟,每次都把最小的放到前边交换
min_loc=i # 默认第一个最小,与后边遍历比较
for j in range(i+1,len(li)):
if li[j]<li[min_loc]:
min_loc=j # 目前的最小元素索引
li[i],li[min_loc]=li[min_loc],li[i]
return li
插入排序
^ 初始时手里(有序区)只有一张牌(默认为元素第一个值)。
^ 每次从无序区(列表右侧区)摸一张牌(依次遍历),插入到有序区的正确(按大小)位置。
python
def insert_sort(li):
for i in range(1,len(li)): # 功n-1趟,i表示摸到牌的下标
tmp=li[i] # 每次摸的牌
j=i-1 # 手里最右侧的
while j>=0 and li[j]>tmp: # 一直往左走
li[j+1]=li[j] # 右移
j-=1
li[j+1]=tmp # 选好位置了
可以看出插入排序时间复杂度为O(n*n)