算法是每一个程序员都必须要认真学习的一门课程,虽然在工作中很少能够用到,但是它能够让我们理解程序的世界。由于前段时间学习了Python,Python语法简洁,便于理解。如果看不明白,可以借助这个网站来帮助理解。
冒泡排序
冒泡排序很简单,重复的遍历数列,依次比较两个元素,满足条件时,将两个元素进行互换。
思路:
- 比较相邻的两个元素,如果第一个元素比第二个元素大,就交换两个元素(里层条件判断)。
- 对第0个元素到第n-i个元素做同样的工作,这时候最大的数就会在数组中最后的位置(外层循环)。
- 对所有的元素重复上面两个步骤
1 | #!/usr/bin/env python3 |
快速排序
快排通常比其他的算法快,因此常常被采用。快排算法体现了分治法的思想。
思路:
- 从数列当中取出一个元素作为基准数。
- 将比基准数大的放到右边,小于或等于它的数都放在左边
- 再对左右区间递归执行步骤2,直到各区间只有一个数
1 | #!/usr/bin/env python3 |
插入排序
对于每个未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
思路:
- 从第一个元素开始,该元素可以认为已经被排序
- 取出下一个元素,在已经排序的元素序列中从后向前扫描
- 如果被扫描的元素(已排序)大于新元素,将该元素后移一位
- 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
- 将新元素插入到该位置后
- 重复步骤2~5
1 | #!/usr/bin/env python3 |
选择排序
对于一个列表l = {k1, k2, … kn},将其从小到大排序。
思路:
- 先从列表l,并选择最小的值minNum,将minNum与k1对换。
- 然后遍历剩下的元素(即k2, … kn)选取最小值minNum,与k2交换
- 以此类推,知道所有元素均排序完毕
1 | #!/usr/bin/env python3 |
归并排序
归并排布是采用分治法的一个非常典型的应用。归并排序的思想就是先递归分解数组,然后再合并数组。
例如:有数列[5, 10, 2, 4, 6],第一次递归后,
思路:
先考虑合并两个有序数组:思路是比较两个数组的最前面的数,谁小就先取谁,取了后相应的指针就往后移一位。然后再比较,直至一个数组为空,最后把另一个数组的剩余部分复制过来即可。
再考虑递归分解:思路是将数组分解成left和right,如果这两个数组内部数据是有序的,那么就可以用上面合并数组的方法将这两个数组合并排序。如何让这两个数组内部是有序的?可以再二分,直至分解出的小组只含有一个元素时为止,此时认为该小组内部已有序。然后合并排序相邻二个小组即可。
1 | #!/usr/bin/env python3 |
希尔排序
希尔排序的基本思想是:将数组中的数据列在一个按照一定的增量列在一个表当中,然后分别进行插入排序。一直重复这个过程,每次都改变这个增量的长度。最后这个表只有一列。
思路:有以下的数组[3, 2, 4, 5, 1, 6, 8, 7]
,将增量列为数组长度的一半,那么得到的表为:
1 | 3 2 4 5 |
然后对每列进行排序,如下表:
1 | 1 2 4 5 |
再次将增量依次折半,并按照下表进行排序,如下表:
1 | 1 2 |
当增量为1的时候,就是插入排序了,重复多次后,当增量为小于0
的时候,排序完成,就得到排序后的数组列表。代码如下:
1 | #!/usr/bin/env python3 |
堆排序
堆排序是采用二叉堆来的数据结构实现的,实质上还是一维数组。二叉堆是一个近似完全二叉树。
二叉堆有以下性质:
- 父节点的键值总是大于或等于(小于或等于)任何一个子节点的键值
- 每个节点的左右子树都是一个二叉堆(都是最大堆或最小堆)
思路:
- 构造最大堆(Build_Max_Heap):若数组下标范围为0~n,考虑到单独一个元素是大根堆,则从下标n/2开始的元素均为大根堆。于是只要从n/2-1开始,向前依次构造大根堆,这样就能保证,构造到某个节点时,它的左右子树都已经是大根堆。
- 堆排序(HeapSort):由于堆是用数组模拟的。得到一个大根堆后,数组内部并不是有序的。因此需要将堆化数组有序化。思想是移除根节点,并做最大堆调整的递归运算。第一次将heap[0]与heap[n-1]交换,再对heap[0…n-2]做最大堆调整。第二次将heap[0]与heap[n-2]交换,再对heap[0…n-3]做最大堆调整。重复该操作直至heap[0]和heap[1]交换。由于每次都是将最大的数并入到后面的有序区间,故操作完后整个数组就是有序的了。
- 最大堆调整(Max_Heapify):该方法是提供给上述两个过程调用的。目的是将堆的末端子节点作调整,使得子节点永远小于父节点 。
1 | #!/usr/bin/env python3 |
时间复杂度与空间复杂度
算法的时间复杂度和空间复杂度可参考这里
排序算法的时间复杂度和空间复杂度对比表: