最近一直在弄博客和爬虫入门的事情,顺带国庆出去旅行了几天。今天终得空把排序这块弄完 。
其实关于排序这块,只要百度一搜,铺天盖地全是,所以我也考虑过要不要弄,但,最后还是决定写这一块,顺带自己复习复习。
下面一个一个来讲:
一、选择排序(选择最小)
排序策略:搜索整个列表,找到最小项的位置,如果该位置不是列表的第一项,就把这两项位置互换。然后算法回到第2个位置,并重复这个过程,如果剩下的列表里,最小项不是第二项,则吧这两项位置互换。当算法到达整个过程的最后一个位置,列表就排好序了。
代码实现:
def selectionSort(lyst):
i = 0 # 从第一位开始
while i < len(lyst) - 1: # 循环次数为列表长度减1
minIndex = i # 先将第i位看作目前为止找到的最小值
j = i+1 # 从第i位的后一位开始比较
while j < len(lyst): # 剩下的字符挨个与从第i位开始的前面比较过的值中的最小值比较
if lyst[j] < lyst[minIndex]: # 如果第j位的值比前面找到的最小值还要小
minIndex = j # 将最小值的位置定为j
j += 1
if minIndex != i: # 如果最小值不是在第i位,就将最小值与第i位的值交换位置
lyst[i],lyst[minIndex]=lyst[minIndex],lyst[i]
i += 1
时间复杂度:O(n2)
注:由于数据项交换只是在外围循环中进行,所以在最坏情况和平均情况下,选择排序的额外的交换各项的开销(如对于很大的数据集合)都是线性的。
二、冒泡排序
排序策略:从列表的开头处开始,并比较一对数据项,直到移动到列表的末尾。每当成对的两项之间的顺序不对时,就交换两项的位置。这样就使得最大的项能在不断的交换中以冒泡的方式排到列表的末尾。然后再次从头开始重复前面的过程,直到倒数第二个项,这样就可以把第二大的项以冒泡的方式排到倒数第二个位置,以此类推,直到该算法从列表的最后一项开始执行,此时,列表已经排好序了。
代码实现:
def bubbleSort(lyst):
for i in range(len(lyst)-1):
for j in range(len(lyst) - i -1): # 确定到倒数第几位为止
if lyst[j] > lyst[j+1]:
lyst[j], lyst[j+1] = lyst[j+1], lyst[j]
改进(如果一开始列表就已经排好序的情况):
def newbubbleSort(lyst):
for i in range(len(lyst)-1):
current_status = False # 设一个bool变量
for j in range(len(lyst)-i-1): # 确定到倒数第几位为止
if lyst[j] > lyst[j+1]:
lyst[j], lyst[j+1] = lyst[j+1], lyst[j]
current_status = True # 若发生值的交换,则变为True
if not current_status:
break # 若第一轮冒泡未发生值的交换,则说明列表已排好序,直接跳出
时间复杂度:O(n2)
改进后的冒泡排序在最好情况下,即列表已排好序的情况下,复杂度为线性阶。
三、插入排序
排序策略:类似抓牌,抓到一张牌,要把这张牌跟手里这些牌比较,然后插入到合适的位置。
代码实现:
def insertionSort(lyst):
for i in range(1, len(lyst)): # 循环的是第二个到最后,按顺序每次取一个数进行插入
min = lyst[i] # 待插入的数设为min
j = i - 1 # 待插入的这个在原本的列表中的左边那个数
while j >= 0 and lyst[j] > min: # 左边的数大于待插入的数,说明我的这个待插入的数应该放在左边的这个数的左边
lyst[j+1] = lyst[j]
j -= 1 # 换完以后再和左边的左边那个数进行比较
lyst[j+1] = min # 待插入的数插入完毕
时间复杂度:O(n2)
最好情况下,即列表已排好序,复杂度为线性阶。