vlambda博客
学习文章列表

【小笔记】8种排序算法的Python实现

1、插入排序

def insertSort(self, array_list): ''' 插入排序 1)将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。 2)从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。 (如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。) :param array_list: :return: ''' for i in range(1, len(array_list)): for j in range(i, 0, -1): if array_list[j] < array_list[j - 1]: array_list[j], array_list[j - 1] = array_list[j - 1], array_list[j] else: break return array_list

2、希尔排序

 def shellSort(self, array_list): ''' 希尔排序,缩小增量排序 :param array_list: :return: ''' gap = len(array_list) // 2 while gap >= 1: for i in range(gap, len(array_list)): j = i while j - gap >= 0: if array_list[j] < array_list[j - gap]: array_list[j], array_list[j - gap] = array_list[j - gap], array_list[j] j -= gap else: break gap //= 2 return array_list

3、选择排序

def selectSort(self, array_list): ''' 选择排序 1)首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置 2)再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。 3)重复第二步,直到所有元素均排序完毕。 :param array_list: :return: ''' for i in range(len(array_list)): tmp_min_index = i for j in range(i + 1, len(array_list)): if array_list[j] < array_list[tmp_min_index]: tmp_min_index = j array_list[i], array_list[tmp_min_index] = array_list[tmp_min_index], array_list[i] return array_list

4、冒泡排序

 def bubbleSort(self, array_list): ''' 冒泡排序 1)比较相邻的元素。如果第一个比第二个大,就交换他们两个。 2)对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。 3)针对所有的元素重复以上的步骤,除了最后一个。 4)持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。 :param array_list: :return: ''' length = len(array_list) while length: for i in range(1, length): if array_list[i] < array_list[i - 1]: array_list[i - 1], array_list[i] = array_list[i], array_list[i - 1] length -= 1 return array_list

5、归并排序

 def mergeSort(self, sorted_list1, sorted_list2): ''' 归并排序 1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列 2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置 3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置 4. 重复步骤3直到某一指针达到序列尾 5. 将另一序列剩下的所有元素直接复制到合并序列尾 :param1 sorted_list1: :param2 sorted_list2: :return: ''' merge_list = [] i, j = 0, 0 while True: if sorted_list1[i] >= sorted_list2[j]: merge_list.append(sorted_list2[j]) j += 1 else: merge_list.append(sorted_list1[i]) i += 1

if i == len(sorted_list1) and j < len(sorted_list2): merge_list.extend(sorted_list2[j:]) break elif i < len(sorted_list1) and j == len(sorted_list2): merge_list.extend(sorted_list1[i:]) break elif i == len(sorted_list1) and j == len(sorted_list2): break return merge_list


6、快速排序

def quickSort(self, begin, end): ''' 快速排序 1 从数列中挑出一个元素,称为 “基准”(pivot), 2 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。 在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。 3 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。 递归的最底部情形,是数列的大小是零或一,也就是永远都已经被排序好了。 虽然一直递归下去,但是这个算法总会退出,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。 def __init__(self): self.array_list = [10,9,8,7,6,5,4,3,2,1,0] :param array_list: :return: ''' if begin < end: key = self.array_list[begin] i, j = begin, end while i < j: while i < j and self.array_list[j] > key: j -= 1 while i < j and self.array_list[i] < key: i += 1 if i < j: self.array_list[i], self.array_list[j] = self.array_list[j], self.array_list[i] key = self.array_list[i] self.quickSort(begin, i - 1) self.quickSort(i + 1, end) return self.array_list

7、堆排序

 def heapSort(self, L): ''' 堆排序 1)创建一个堆H[0..n-1] 2)把堆首(最大值)和堆尾互换        3)把堆的尺寸缩小1        4)重复步骤2,直到堆的尺寸为1 ''' from collections import deque def swap_param(L, i, j): L[i], L[j] = L[j], L[i]            return L             def heap_adjust(L, start, end):            temp = L[start] i = start            j = 2 * i while j <= end: if (j < end) and (L[j] < L[j + 1]): j += 1 if temp < L[j]: L[i] = L[j] i = j j = 2 * i else: break            L[i] = temp                    L_length = len(L) - 1 first_sort_count = L_length // 2 for i in range(first_sort_count):            heap_adjust(L, first_sort_count - i, L_length) for i in range(L_length - 1): L = swap_param(L, 1, L_length - i)            heap_adjust(L, 1, L_length - i - 1) return [L[i] for i in range(1, len(L))]

8、基数排序

 def radixSort(self, array_list): ''' 基数排序,是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。 由于整数也可以表达字符串(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数。 简单来说,就是把数据分组,放在一个个的桶中,然后对每个桶里面的在进行排序。 例如要对大小为[1..1000]范围内的n个整数A[1..n]排序 首先,可以把桶设为大小为10的范围,具体而言,设集合B[1]存储[1..10]的整数,集合B[2]存储(10..20]的整数,……集合B[i]存储((i-1)*10,i*10]的整数,i=1,2,...100。总共有100个桶。 然后,对A[1..n]从头到尾扫描一遍,把每个A[i]放入对应的桶B[j]中。再对这100个桶中每个桶里的数字排序,这时可用冒泡,选择,乃至快排,一般来说任何排序法都可以。 依次输出每个桶里面的数字,且每个桶中的数字从小到大输出,这样就得到所有数字排好序的结果。
:param array_list: :return: ''' i = 0 # 记录当前正在排拿一位,最低位为1 max_num = max(array_list) # 最大值 j = len(str(max_num)) # 记录最大值的位数 while i < j: bucket_list = [[] for _ in range(10)] # 初始化桶数组 for x in array_list: bucket_list[int(x / (10 ** i)) % 10].append(x) # 找到位置放入桶数组 array_list.clear() for x in bucket_list: # 放回原序列 for y in x: array_list.append(y) i += 1 return array_list

最后,附上一个排序算法的比较表,以备查看。