原地排序:空间复杂度为O(1)的排序
稳定排序:排序完之后相同值的元素的前后位置不会改变。
冒泡排序:
冒泡排序只会操作相邻的两个数据。每次冒泡操作都会对相邻的两个元素比较,看是否满足大小关系要求。如果不满足就让他两互换。一次冒泡操作至少会让一个元素移动到它应该到的位置,重复n次,就完成了n个数据的排序工作。
时间复杂度 最好O(n),最坏O(n^2),平均O(n^2)
空间复杂度O(1)
插入排序:
我们将数组中的数据分为两个区间,已排序区间和未排序区间。初始已排序区间只有一个元素,就是数组的第一个元素。插入算法的核心思想是取未排序区间的中元素,在已经排序区间中找到合适的插入位置将其插入,并保证
已排序区间一直有序。重复这个过程,直到未排序区间中元素为空,算法结束。
时间复杂度 最好O(n),最坏O(n^2),平均O(n^2)
空间复杂度O(1)
选择排序
选择排序算法的实现思路和插入排序类似,也分已排序区间和未排序区间。但是选择排序每次会从未排序区间中找到最小的元素,将其放在已排序区间的末尾。
时间复杂度 最好O(n^2),最坏O(n^2),平均O(n^2)
空间复杂度O(1)
快速排序:
如果要排序数组中下标从p到r之间的一组数据,我们选择p到r之间的任意一个数据作为pivot(分区点)。
我们遍历p到r之间的数据,将小于pivot的放到左边,将pivot放到中间。经过这一步骤之后,数组p到r之间的数据就分为三部分,前面p到q-1之间的都是小于pivot的,中间pivot,后面的q+1到r之间是大于pivot的。根据分治、递归思想,我们可以递归排序下标从p到q-1之间的数据和下标从q+1到r之间的数据,直到区间缩小为1,就说明所有的数据有序了。
时间复杂度 O(nlogn)
空间复杂度O(n)
归并排序:
如果要排序一个数组,我们先把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就有序了。归并排序使用的是分治思想。分治是一种解决问题的处理思想,递归是一种编程技巧。
时间复杂度 O(nlogn)
空间复杂度O(n)
桶排序:
将要排序的数据分到几个有序的桶里,每个桶的数据再进行单位排序。桶内排完之后,再把每个桶的数据按照顺序依次取出,组成的序列就是有序的了。
计数排序:
技术计数排序就是桶排序的一种特殊情况。当要排序的n个数据,所处范围并不大,比如最大值为k,我们就可以把数据分为k个桶。每个桶内的值都是相同的,省掉了桶内排序的时间。
时间复杂度O(n)
空间复杂度O(n)
基数排序:
1.算法原理(以排序10万个手机号为例来说明)
1)比较两个手机号码a,b的大小,如果在前面几位中a已经比b大了,那后面几位就不用看了。
2)借助稳定排序算法的思想,可以先按照最后一位来排序手机号码,然后再按照倒数第二位来重新排序,以此类推,最后按照第一个位重新排序。
3)经过11次排序后,手机号码就变为有序的了。
4)每次排序有序数据范围较小,可以使用桶排序或计数排序来完成。
2.使用条件
1)要求数据可以分割独立的“位”来比较;
2)位之间由递进关系,如果a数据的高位比b数据大,那么剩下的地位就不用比较了;
3)每一位的数据范围不能太大,要可以用线性排序,否则基数排序的时间复杂度无法做到O(n)。