快速排序
原理
- 快速排序是冒泡排序的优化
- 有没有既不浪费空间又可以快一点的排序算法呢?那就是“快速排序”啦!光听这个名字是不是就觉得很高端呢。
快速排序快的原因
- 因为相比冒泡排序,每次交换是跳跃式的。每次排序的时候设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。这样在每次交换的时候就不会像冒泡排序一样每次只能在相邻的数之间进行交换,交换的距离就大的多了。因此总的比较和交换次数就少了,速度自然就提高了。当然在最坏的情况下,仍可能是相邻的两个数进行了交换。因此快速排序的最差时间复杂度和冒泡排序是一样的都是O(N2),它的平均时间复杂度为O(NlogN)。其实快速排序是基于一种叫做“二分”的思想。
不稳定排序
- 当待排序元素类似[6,1,3,7,3]且基准元素为6时,经过分区,形成[1,3,3,6,7],两个3的相对位置发生了改变,所是快速排序是一种不稳定排序。
快速排序优化
- 当待排序序列长度分割到一定大小后,使用插入排序。
- 对于很小和部分有序的数组,快排不如插排好。当待排序序列的长度分割到一定大小后,继续分割的效率比插入排序要差,此时可以使用插排而不是快排
- 优化切分元素选择
- 最理想的方法是,选择的基准恰好能把待排序序列分成两个等长的子序列。
- 方法一:固定基准元(基本的快速排序)
- 思想:取序列的第一个或最后一个元素作为基准元。
- 随机基准元
- 思想:取待排序列中任意一个元素作为基准元。
- 引入的原因:在待排序列是部分有序时,固定选取基准元使快排效率底下,要缓解这种情况,就引入了随机选取基准元。
- 方法三:三数取中
- 最佳的划分是将待排序的序列分成等长的子序列,最佳的状态我们可以使用序列的中间的值,也就是第N/2个数。可是,这很难算出来,并且会明显减慢快速排序的速度。这样的中值的估计可以通过随机选取三个元素并用它们的中值作为基准元而得到。事实上,随机性并没有多大的帮助,因此一般的做法是使用左端、右端和中心位置上的三个元素的中值作为基准元。显然使用三数中值分割法消除了预排序输入的不好情形,并且减少快排大约14%的比较次数。