选择排序与快速排序--算法注释
# 选择排序
# 策略:搜索整个列表,找到最小项的位置,如果该位置不是列表的第一个位置,算法就交换在这两个位置的项 # 时间复杂度最好情况为线性阶,最坏或者平均情况均为平方阶 def selectionsort(lyst): i = 0 while i < len(lyst) - 1: minIndex = i # 先假设第一个位置是最小值位置 j = i + 1 # 从它后面位置开始进行比较 while j < len(lyst): # 将列表遍历,找到最小值 if lyst[j] < lyst[minIndex]: # 如果比开始假设最小值小,那就将最小值索引赋给现在的 minIndex = j j += 1 if minIndex != i: # 第一次遍历完后找到最小值的索引不再是原来的i了,就可以将其与i的位置调换 lyst[i], lyst[minIndex] = lyst[minIndex], lyst[i] i += 1 return lyst lyst = [9, 7, 5] print(selectionsort(lyst))
冒泡排序策略是从列表的开头出开始,并且比较一对数据项,直到移动到列表的末尾;每当成对的两项之间的顺序不正确的时候,算法就交换位置。
快速排序
时间复杂度最坏的情况是平方阶,其他情况是O(nlog2n)
# Created by fly at 2019/2/24 # 思想是: 递归和分而治之 def partition(lyst, left, right): # 首先将基准点与最后一项交换位置 middle = (left + right) // 2 pivot = lyst[middle] lyst[middle] = lyst[right] lyst[right] = pivot # 在第一项之前建立一个边界 boundary = left # 将小于基准点的项移动到左边 for i in range(left, right): # 第一次分割操作时,是扫描整个列表的 if lyst[i] < pivot: # 将小于基准点的项换到边界的位置 lyst[i], lyst[boundary] = lyst[boundary], lyst[i] boundary += 1 # 边界向后移动,继续扫描小点 # 整个扫描完毕后已经没有比基准点小的了,这时的边界位置即是新的子列表(小于基准点项的集合)的右边 lyst[right], lyst[boundary] = lyst[boundary], lyst[right] return boundary # 递归函数:上面的函数结束将列表分割成两个子列表,因此我们要想办法让上面的算法统一作用于子列表 def quicksort_helper(lyst, left, right): if left < right: pivot_location = partition(lyst, left, right) # 函数返回的边界是子列表的右边,按照上面的算法,第一步自然是将基准项与最右边项交换 # 递归 quicksort_helper(lyst, left, pivot_location - 1) # 因为前面一句是已经进行一次分割,所以这是基准点左边的列表(不包括基准点)进行排序 quicksort_helper(lyst, pivot_location + 1, right) # 对基准点右边的列表排序 def quicksort(lyst): quicksort_helper(lyst, 0, len(lyst) - 1) import random def main(size = 5, sort = quicksort): # 加入一些默认参数 lyst = [] for count in range(size): lyst.append(random.randint(1, size + 1)) # 5个[1, 21]之间的随机数组成的列表 print(lyst) sort(lyst) # 这一步调用函数,已经使得lyst内容改变,所以后面打印lyst有结果 print(lyst) # 如果直接写print(sort(lyst)),结果是None,因为定义quicksort函数后面没有加 return lyst, if __name__ == '__main__': main()
注意:Python list内置排序方法有sort(),sorted()。用list.sort()方法来排序,此时list本身将被修改,但sorted()不会;还有list.sort()方法仅被定义在list中,而sorted()方法对所有的可迭代序列都有效。时间复杂度最坏和平均情况为O(nlogn)
浙公网安备 33010602011771号