题目分析
这个题目非常简单,初学语言的小伙伴们都应该可以求解。排序也是算法中最基础最核心的问题之一,今天不是讲解这一道题目,而是给小伙伴们讲解常见的十种排序算法,就按照题目的要求,升序排列。
稳定排序和不稳定排序
在排序算法性能的比较中,除了时间复杂度和空间复杂度外,还有一个因素是排序是否稳。什么是稳定呢?简单来说,稳定是两个相同的数字不会因为排序算法而导致顺序调换,如1,3(1),5,3(2)排序后为1,3(2),3(1),5,本来第一个3和第二个3交换了顺序,那么这个排序就是不稳定的。对于纯数字来说,稳定和不稳定没有太大意义,但是如果对于某个类,将某个属性进行排序,则就非常有必要了。举个例子,有100个人到银行排队,它们都是普通客户,这时候来了一个VIP客户,这时需要对数据进行排序,将VIP客户的优先级提高,但是如果排序是不稳定的,则后面100个人的顺序将会被打乱,这时,之前排在第一个的人肯定是不愿意的。这就是不稳定排序造成的后果。
冒泡排序
冒泡排序可能是我们最早接触的排序算法之一了,什么是冒泡排序呢?比较相邻的两个数值,如果前一个数大于后一个数,则交换两个数,就像吐泡泡一样,每一轮迭代会将最大的数放在最后,而且可以添加一个监视器,如果某一轮迭代都没有发生任何依次交换,说明这个序列已经是有序的,则可以提前停止。冒泡排序算法的时间复杂度为$O(n^2)$,最好情况为$O(n)$,最坏情况为$O(n^2)$,空间复杂度$O(1)$,稳定排序。
1 | class Solution: |
选择排序
选择排序思路也非常简单,每次从剩余数组中选择一个最小的放在当前位置上,选择排序算法的时间复杂度为$O(n^2)$,最好情况为$O(n^2)$,最坏情况为$O(n^2)$,空间复杂度$O(1)$,不稳定排序。
1 | class Solution: |
插入排序
插入排序类似于冒泡排序,插入排序保证当前位置以前的都是有序的,将当前位置从后向前通过交换的方式,插入到之前有序的位置中,插入排序算法的时间复杂度为$O(n^2)$,最好情况为$O(n)$,最坏情况为$O(n^2)$,空间复杂度$O(1)$,稳定排序。
1 | class Solution: |
快速排序
快速排序是一种面试常问的排序方法,其思想是每次选择一个基准值,将小于等于基准值的放在左边,大于基准值的放在右边,然后递归左边和右边两个子序列,快速排序算法的时间复杂度为$O(nlog(n))$,最好情况为$O(nlog(n))$,最坏情况为$O(n^2)$,空间复杂度$O(log(n))$,不稳定排序。
1 | class Solution: |
归并排序
归并排序利用了一种分治的思想,先对序列进行分解,分解成长度为1的n个子序列,这n个子序列因为长度为1,故都是有序的,然后再进行合并,合并的时候就是两个有序数组进行合并,因此排序速度会大大提升,归并排序算法的时间复杂度为$O(nlog(n))$,最好情况为$O(nlog(n))$,最坏情况为$O(nlog(n))$,空间复杂度$O(n)$,稳定排序。
1 | class Solution: |
桶排序
桶排序首先建立k个桶,每个桶有一定的范围,将原始序列分桶装入,这样排序时只要每个桶是有序的,则整体是有序的,可以降低时间复杂度。桶排序算法的时间复杂度为$O(n + k)$,最好情况为$O(n + k)$,最坏情况为$O(n^2)$,空间复杂度$O(n + k)$,稳定排序。
1 | class Solution: |
计数排序
计数排序的原理也很简单,用数组下标统计元素出现的个数即可,因为数组下标是升序排列的,因此输出时只需要按照数组下标顺序依次输出即可,缺点也很明显,对非整数数组进行排序不太方便。计数排序算法的时间复杂度为$O(n + k)$,最好情况为$O(n + k)$,最坏情况为$O(n + k)$,空间复杂度$O(n)$,稳定排序。
1 | class Solution: |
希尔排序
希尔排序类似于插入排序,但是不同点是插入排序增量为1,要插入的值从后向前,一个一个比较,而希尔排序是从后向前有间隔的比较,间隔不同时间复杂度不同,一般按照总长度二分的方式设置间隔。希尔排序算法的时间复杂度为$O(n^{1.3})$,最好情况为$O(n)$,最坏情况为$O(n^2)$,空间复杂度$O(1)$,不稳定排序。
1 | class Solution: |
堆排序
堆排序使用了最大堆的概念,指父节点的值大于孩子节点的值,首先建立一个最大堆,然后交换最后一个元素与堆顶元素的值,接着对最大堆进行下沉操作,如果交换进去的值小于孩子节点,则使其下沉,更新最大堆,然后继续交换得到第二大的值,并重复上面的操作即可得到升序的数组。堆排序算法的时间复杂度为$O(nlog(n))$,最好情况为$O(nlog(n))$,最坏情况为$O(nlog(n))$,空间复杂度$O(1)$,不稳定排序。
1 | class Solution: |
基数排序
基数排序类似于桶排序和计数排序,这个排序方式先设置10个桶,按照十进制位进行排序,先排个位,将个位按照升序放入桶内,然后将桶内的数字依次取出,然后排十位,百位,依次下取直到最高位为止,最后将最高位排序后的元素从桶内依次取出即可完成升序排列,缺点和计数排序相同,对非整数数组进行排序不太方便。基数排序算法的时间复杂度为$O(nk)$,最好情况为$O(nk)$,最坏情况为$O(nk)$,空间复杂度$O(n)$,稳定排序。
1 | class Solution: |
刷题总结
排序问题是算法经久不衰的考点之一,这十种方法各有利弊,没有绝对的好与不好,只有不同的适用场景罢了,其中最重要的几个排序方法是冒泡排序,快速排序,归并排序,堆排序。由于其面试出题过于频繁,很多公司已经不考这个简单的算法问题,但是小伙伴们也必须要掌握它。