Sort 算法1:冒泡排序 思想
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素做同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较 [1]。
参考资料:
吕新平、刘宏铭.二级公共基础知识实战训练教程:西安交通大学出版社,2006.02:30页
python 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 # !/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2020/08/01 # @Author : renyb # @File : sort.py def bubble_sort(arr): # 这个循环负责设置冒泡排序进行的次数 for i in range(len(arr) - 1): # j为列表下标 for j in range(len(arr) - i - 1): if arr[j] > arr[j + 1]: arr[j], arr[j + 1] = arr[j + 1], arr[j] return arr if __name__ == "__main__": array = [2,3,5,7,1,4,6,15,5,2,7,9,10,15,9,17,12] print(bubble_sort(array))
算法2:选择排序 思想
首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕 [1]。
参考文档:
Ajay Kumar.Data Structure for C Programming:Firewall Media,2004:268-270
Hosam M.Mahmoud.Sorting: A Distribution Theory:John Wiley&Sons, Inc,2000:139-142
python 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 def find_max_index (arr, n ): max_index = 0 for i in range(1 , n): if arr[i] > arr[max_index]: max_index = i return max_index def select_sort (arr ): i = len(arr) while i > 1 : max_index = find_max_index(arr, i) arr[i-1 ], arr[max_index] = arr[max_index], arr[i-1 ] i -= 1 return arr if __name__ == "__main__" : arr = [2 ,3 ,5 ,7 ,1 ,4 ,6 ,15 ,5 ,2 ,7 ,9 ,10 ,15 ,9 ,17 ,12 ] print(select_sort(arr))
算法3:插入排序 思想
插入排序的工作方式像许多人排序一手扑克牌。开始时,我们的左手为空并且桌子上的牌面向下。然后,我们每次从桌子上拿走一张牌并将它插入左手中正确的位置。为了找到一张牌的正确位置,我们从右到左将它与已在手中的每张牌进行比较。拿在左手上的牌总是排序好的,原来这些牌是桌子上牌堆中顶部的牌 [1]。
参考文档:
(美)科尔曼等著;殷建平等译.算法导论.北京:机械工业出版社,2013:17-29
python 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 def insert (arr, i ): temp = arr[i] while arr[i-1 ] > temp: arr[i] = arr[i-1 ] i -= 1 if i == 0 : break arr[i] = temp def insert_sort (arr ): for i in range(1 , len(arr)): insert(arr, i) return arr if __name__ == "__main__" : arr = [2 ,3 ,5 ,7 ,1 ,4 ,6 ,15 ,5 ,2 ,7 ,9 ,10 ,15 ,9 ,17 ,12 ] print(insert_sort(arr))
算法4:快速排序 思想
设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它左边,所有比它大的数都放到它右边,这个过程称为一趟快速排序。值得注意的是,快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动 [1]。
一趟快速排序的算法是:
1)设置两个变量i、j,排序开始的时候:i=0,j=N-1;
2)以第一个数组元素作为关键数据,赋值给key ,即key =A[0];
3)从j开始向前搜索,即由后开始向前搜索(j–),找到第一个小于key 的值A[j],将A[j]和A[i]的值交换;
4)从i开始向后搜索,即由前开始向后搜索(i++),找到第一个大于key 的A[i],将A[i]和A[j]的值交换;
5)重复第3、4步,直到i=j; (3,4步中,没找到符合条件的值,即3中A[j]不小于key ,4中A[i]不大于key 的时候改变j、i的值,使得j=j-1,i=i+1,直至找到为止。找到符合条件的值,进行交换的时候i, j指针位置不变。另外,i==j这一过程一定正好是i+或j-完成的时候,此时令循环结束)。
参考资料:
陈雄达,关晓飞,殷俊锋,张华隆编.数学实验:同济大学出版社,2016.08:第135页
python 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 def quick_sort (arr ): if len(arr) >= 2 : mid = arr[0 ] left, right = [], [] arr.remove(mid) for num in arr: if num >= mid: right.append(num) else : left.append(num) return quick_sort(left) + [mid] + quick_sort(right) else : return arr if __name__ == "__main__" : array = [2 ,3 ,5 ,7 ,1 ,4 ,6 ,15 ,5 ,2 ,7 ,9 ,10 ,15 ,9 ,17 ,12 ] print(quick_sort(array))
算法5:堆排序 思想
在堆的数据结构中,堆中的最大值总是位于根节点(在优先队列中使用堆的话堆中的最小值位于根节点)。堆中定义以下几种操作 [1]:
最大堆调整(Max Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点
创建最大堆(Build Max Heap):将堆中的所有数据重新排序
堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算
参考资料:
Floyd, Robert W. (1964), “Algorithm 245 - Treesort 3”, Communications of the ACM, 7 (12): 701, doi:10.1145/355588.365103
python 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 def heapify (tree, n, i ): if i >= n: return c1 = 2 * i + 1 c2 = 2 * i + 2 max = i if c1 < n and tree[c1] > tree[max]: max = c1 if c2 < n and tree[c2] > tree[max]: max = c2 if max != i: tree[max], tree[i] = tree[i], tree[max] heapify(tree, n, max) def build_heap (tree, n ): last_node = n - 1 parent = (last_node - 1 ) // 2 while parent >= 0 : heapify(tree, n, parent) parent -= 1 def heap_sort (tree ): n = len(tree) build_heap(tree, n) while n > 1 : tree[0 ], tree[n-1 ] = tree[n-1 ], tree[0 ] build_heap(tree, n-1 ) n -= 1 if __name__ == "__main__" : tree = [2 , 1 , 3 , 5 , 10 , 4 ] heap_sort(tree) print(tree)
算法6:归并排序 思想
归并操作,也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。
如 设有数列{6,202,100,301,38,8,1}
初始状态:6,202,100,301,38,8,1
第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3;
第二次归并后:{6,100,202,301},{1,8,38},比较次数:4;
第三次归并后:{1,6,8,38,100,202,301},比较次数:4;
总的比较次数为:3+4+4=11;
逆序数为14;
归并操作的工作原理如下:
第一步:申请空间,使其大小为两个已经排序 序列之和,该空间用来存放合并后的序列
第二步:设定两个指针 ,最初位置分别为两个已经排序序列的起始位置
第三步:比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置
重复步骤3直到某一指针超出序列尾
将另一序列剩下的所有元素直接复制到合并序列尾
python 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 def merge (left, right ): i, j = 0 , 0 record = [] while i < len(left) and j < len(right): if left[i] < right[j]: record.append(left[i]) i += 1 else : record.append(right[j]) j += 1 record += left[i:] record += right[j:] return record def merge_sort (arr ): if len(arr) <= 1 : return arr i = len(arr) // 2 left = merge_sort(arr[:i]) right = merge_sort(arr[i:]) return merge(left, right) if __name__ == "__main__" : arr = [2 ,3 ,5 ,7 ,1 ,4 ,6 ,15 ,5 ,2 ,7 ,9 ,10 ,15 ,9 ,17 ,12 ] print(merge_sort(arr))