yangjingdong00 2020-07-05
思想:冒泡排序(Bubble Sort)是一种简单直观的排序算法。它的工作原理是:它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
实例:
def bubbleSort(alist): # 找最大值的方式是通过对列表中的元素进行两两比较,值大的元素逐步向后移动 # 序列中有n个元素,两两比较的话,需要比较n-1次 n = len(alist) for j in range(n - 1): # 外层循环次数递增,内层循环次数递减 for i in range(n - 1 - j): # 循环n-1-j次,控制两两比较的次数 if alist[i] > alist[i + 1]: # 如果前面的元素大于后面的元素,交换两个元素的位置 alist[i], alist[i + 1] = alist[i + 1], alist[i] else: # 如果后面的元素大于前面的元素,则不作任何操作 pass return alist alist = [2, 6, 0, 9, 4] print(bubbleSort(alist))
思想:选择排序(Selection Sort)也是一种简单直观的排序算法。它的工作原理是:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
实例:
# 将乱序序列中的元素两两比较,找出最大值,然后直接将最大值放置到序列最后的位置,将最大值直接和最后一个元素交换位置 def selectionSort(alist): n = len(alist) for j in range(n - 1): max_index = 0 # 最大值元素的下标,一开始假设下标为0的元素为最大值 for i in range(n - 1 - j): if alist[max_index] < alist[i + 1]: max_index = i + 1 # 循环结束后max_index就一定是最大值的下标 alist[n - 1 - j], alist[max_index] = alist[max_index], alist[n - 1 - j] return alist alist = [3, 9, 8, 2, 0] print(selectionSort(alist))
思想:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫码,找到相应位置并插入
实例:
# 思路: # 需要将原始序列分成两部分:有序部分,无序部分 # 将无序部分中的元素逐一插入到有序部分中 # 注意:初始情况下,有序部分为乱序序列的第一个元素,无序部分为乱序序列的n-1个元素 # 乱序序列:[3,8,5,7,6] # [3,,,,8,5,7,6]:3就是初始的有序部分,8,5,7,6就是初始的无序部分 # [3,8,,,,5,7,6] # [3,5,8,,,,7,6] # [3,5,7,8,,,,6] # [3,5,6,7,8,,,] # 定义一个变量i,i表示的是有序部分元素的个数&无序部分第一个元素下标。 def insertionSort(alist): 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] i -= 1 else: break return alist alist = [3, 8, 5, 7, 6] print(insertionSort(alist))
思想:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,在对全体记录进行依次直接插入排序。希尔排序也成递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。
实例:
def shellSort(alist): grep = len(alist) // 2 # 初始增量 while grep >= 1: for i in range(grep, len(alist)): while i > 0: if alist[i - grep] > alist[i]: alist[i - grep], alist[i] = alist[i], alist[i - grep] i -= grep else: break grep //= 2 # 缩减增量 return alist alist = [1, 3, 7, 9, 8, 4, 2] print(shellSort(alist))
思想:
实例:
# 核心操作:将基数mid放置到序列中间,使得基数左侧都是比它小的,右侧是比它大的 def quickSort(alist, left, right): low = left # 第一个元素的下标 high = right # 最后一个元素的下标 if low > high: # 结束递归的条件 return mid = alist[low] # 基数,初始值为序列的第一个元素 while low < high: # 先偏移high while low < high: if mid < alist[high]: # 向左偏移high high -= 1 else:# 将high指向的数值放置到左侧的空位 alist[low] = alist[high] break # 向右偏移low while low < high: if mid >= alist[low]: # 向右偏移low low += 1 else:# 将low指向的数值放置到右侧的空位 alist[high] = alist[low] break if low == high: alist[low] = mid # 上述为核心操作,需要将核心操作递归左右到左右子序列中 quickSort(alist, left, low - 1)# 将quickSort作用到左侧序列中 quickSort(alist, high + 1, right)# 将quickSort作用到右侧序列中 return alist alist = [0, 9, 4, 7, 2, 3, 1] print(quickSort(alist, 0, len(alist) - 1))
要知道时间复杂度只是描述一个增长趋势,复杂度为O的排序算法执行时间不一定比复杂度为O长,因为在计算O时省略了系数、常数、低阶。实际上,在对小规模数据进行排序时,n2的值实际比 knlogn+c还要小。