冒泡排序
''' 冒泡排序算法的运作如下: 比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。最后的元素会是最大的数。 针对所有的元素重复以上的步骤,除了最后一个。 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。 ''' def bubble_sort(lst): for j in range(len(lst)-1,1,-1): # j 为比较的次数,不断减少。每进行一次排序,最后面的 "最大的数" 就不断增加,所以需要排序的次数就越来越少 for i in range(j): # 不包括j if lst[i] > lst[i+1]:#如果前面的元素大于后面的元素 # 不断将最大的元素向后移 lst[i],lst[i+1] = lst[i+1],lst[i] li = [54,26,93,17,77,31,44,55,20] bubble_sort(li) print(li)
希尔排序
''' 将数组列在一个表中,分别进行插入排序。先以步长为一半,列表。然后对每一列进行排序。 然后将排好序的,再按照步长为一半,列表进行排序。 最后进行插入排序 ''' def shell_sort(lst): n = len(lst) gap = n//2 #按照总长度的一半进行分列,然后进行 行排序 while gap > 0: for i in range(gap,n): j = i #按照步长进行排序 while j>= gap and lst[j-gap] > lst[j]:#对索引位置进行有规律的使用 # j-gap表示每一列上的元素,j发生变化,列发生变化 lst[j-gap],lst[j] = lst[j],lst[j-gap] j -= gap#向上一行 gap = gap//2#缩小比较的列的个数 lst = [54,26,93,17,77,31,44,55,20] shell_sort(lst) print(lst)
归并排序
''' 先递归分解数组,后合并数组 将数组分解最小之后,然后合并两个有序数组。 比较两个数组最前面的数,谁小就先取谁, 取了之后相应的指针就向后移一位,然后再比较,直到一个数组为空 最后把另一个数组的剩余部分添加过来 ''' def merge_sort(alist): if len(alist) <= 1: # 如果只有一个元素,则不需要进行排序,直接返回结果 return alist # 二分分解 num = len(alist)//2 left = merge_sort(alist[:num]) right = merge_sort(alist[num:]) # 合并 return merge(left,right) def merge(left, right): '''合并操作,将两个有序数组left[]和right[]合并成一个大的有序数组''' #left与right的下标指针 l, r = 0, 0 result = [] while l<len(left) and r<len(right): if left[l] < right[r]: # 当左面的第l个元素小于右面的第r元素时 result.append(left[l])#添加左面的第一个元素 l += 1#左面元素l +1 else: result.append(right[r])#如果不大于,右面元素r +1 r += 1 result += left[l:]#如果左面还有没进行比较的元素、则全部添加到比较后的result内部 result += right[r:] return result alist = [54,26,93,17,77,31,44,55,20] sorted_alist = merge_sort(alist) print(sorted_alist)
快速排序
''' 通过一趟排序将要排序的数据分割成独立的两部分, 其中一部分的所有数据都比另一部分数据小, 再按此方法对这两部分分别进行快速排序。 步骤为: 从数列中挑出一个元素,称为"基准"(pivot), 重新排序数列,所有元素比基准值小的摆放在基准前面, 所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区结束之后, 该基准就处于数列的中间位置。这个称为分区(partition)操作。 递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。 ''' def quick_sort(alist, start, end): """快速排序""" # 递归的退出条件 if start >= end: return # 设定起始元素为要寻找位置的基准元素 mid = alist[start] # low为序列左边的由左向右移动的游标 low = start # high为序列右边的由右向左移动的游标 high = end while low < high: # 如果low与high未重合,high指向的元素不比基准元素小,则high向左移动 while low < high and alist[high] >= mid: # mid是一开始的元素 high -= 1 # 将high指向的元素放到low的位置上 alist[low] = alist[high] # 在while循环内部不断发生位置转换 # 如果low与high未重合,low指向的元素比基准元素小,则low向右移动 while low < high and alist[low] < mid: low += 1#寻找最小元素的位置 # 将low指向的元素放到high的位置上 alist[high] = alist[low] # 退出循环后,low与high重合,此时所指位置为基准元素的正确位置 # 将基准元素放到该位置 alist[low] = mid # 对基准元素左边的子序列进行快速排序 quick_sort(alist, start, low-1) # 对基准元素右边的子序列进行快速排序 quick_sort(alist, low+1, end) alist = [54,26,93,17,77,31,44,55,20] quick_sort(alist,0,len(alist)-1) print(alist)
插入排序
''' 通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描, 找到相应位置并插入。插入排序在实现上,在从后向前扫描过程中, 需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。 ''' def insert_sort(lst): for i in range(1,len(lst)): # 比较的次数 for j in range(i,0,-1): # 需要比较的次数不断增加 # 需要插入的元素不断增加,i不断变大 if lst[j] < lst[j-1]: lst[j],lst[j-1] = lst[j-1],lst[j] lst = [54,26,93,17,77,31,44,55,20] insert_sort(lst) print(lst)
选择排序
''' 首先在未排序序列中找到最小(大)元素, 存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素, 然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。 ''' def selection_sort(lst): n = len(lst) for i in range(n-1): for j in range(i+1,n): # 未排序序列,i不断增加,为第一个未排序序列元素 min_index = i #先令 i 为 min_index if lst[j] < lst[min_index]: min_index = j #如果min_index大于j 则交换位置 if min_index != i: #min_index发生了变化,不是 i lst[i],lst[min_index] = lst[min_index],lst[i] lst = [54,226,93,17,77,31,44,55,20] selection_sort(lst) print(lst)
2020-07-25