@[TOC](目录)
# 冒泡排序:
https://www.jianshu.com/p/1458abf81adf
时间复杂度的最好情况:一开始就是正序,则需要扫描1趟,比较 n-1 次, 移动 0 次。 O(n)
时间复杂度的最差情况:一开始是反序,则需要扫描 n - 1 躺。 O(n的平方)
平均时间复杂度 O(n的平方)
评价:相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。
# 快速排序
概念:基准值(每一趟快速排序的依据), 哨兵(i,j就是一前一后的两个下标,j, 要向前走(--j), i要向后走(++i))
基本思想:每一趟快速排序,选择一个基准值,这一趟快速排序之后,比基准值大的数都在基准值右边,比基准值小的数都在基准值左边,基准值在中间(不是正中间的意思)。 一趟快速排序之后,返回基准值当前位置,然后左边对[left, 基准值位置-1]子数组排序,右边则是[基准值位置+1, right]子数组排序。利用递归算法,对分治后的子数组进行排序。
一趟快速排序步骤:
- 先从最右位置往左开始找直到找到一个小于(不包括等于)基准数的值,记录下该值的位置(记作 right)。
- 再从最左位置往右找直到找到一个大于(不包括等于)基准数的值,记录下该值的位置(记作 left)。
- 如果位置left<right,则交换i和j两个位置上的值,然后继续从(right-1)的位置往前和(left+1)的位置往后重复上面比对基准数然后交换的步骤。
- 如果执行到left==right,表示本次比对已经结束,将最后left的位置的值与基准数做交换,此时基准数就找到了临界点的位置k,位置k两边的数组都比当前位置k上的基准值或都更小或都更大。
- 上一次的基准值已经把数组分为了两半。
代码:(实现细节,不止这一种,但是为了应付面试,可以强行记下来)
总结:快速排序是对冒泡排序的一种改进,采用了分而治之的思想。
一趟快排的时间复杂度是O(n), 而快排的总的时间复杂度和趟数有关(趟数取决于基准值是否合理)。最好情况下,O(nlog2n), 最坏的情况, O(n的平方)。可以证明,快速排序的平均时间复杂度是O(nlog2n)。快速排序被认为是目前最好的一种内部排序方法。
评价:快速排序是一种不稳定排序算法。
# 随机快速排序:
动机:为了降低快速排序的时间复杂度是O(n的平方)这种情况的概率,需要随机选择基准值。
代码:(将随机的一个位置的元素和首元素交换,其他代码不用改变)
效果: