快速排序
思想:双指针法(左右指针法)
时间复杂度:O(n log n)(最理想的情况下)
最坏的情况:输入的数组已经是有序的或者接近有序时 快速排序的性能会退化到O(n^2)
我们的快速排序其实就是让两个指针一左一右进行移动
例如我们要升序
就是让右边的指针找到小的数 左边的指针找到大的数 但小于谁 大于谁 我们不妨设定一个基准数 当找到这两个数后令其互换 当左右指针相遇时 将相遇处的值和基准数互换 这样基准数左边的数都将小于基准数 基准数右边的数都将大于基准数 然后我们在分别对左 右两个序列进行排序 直到左 右序列仅剩一个元素或不剩下元素了
变量:left right i j t tmp
为了防止left right移动之后 无法再使用原先位置
我们这里使用i j代替left right进行移动
t用于交换指针i j处的数 tmp用于存储基准数
- 设基准数tmp(我们可以将其设为最左边)
- 移动i j(如果基准数在最左边时 我们先让j(替代right移动)进行移动)
- i用于寻找大于基准数的数 j用于寻找小于基准数的数
- (当i小于j时)当j找到一个小于基准数的数 再让i移动 然后使i与j位置处的数进行交换
- 当i与j相遇时 让基准数和相遇处的数进行交换
- 重复上述步骤
注意:当基准数在最左边时 先令j移动 当基准数在最右边时 先让i移动
这里我就不给大家解释原因了 感兴趣的可以自己去想想 如果不这样可能会出错
现在我们以一个例子来解释,如下图:
在这里我们让j先移动 找到小于基准数6的数 再让i找到大于基准数的数 两者交换
当i与j相遇时 将相遇处的数和基准数交换
当基准数和i j相遇处的数交换后 很好的将数据分成了左右两部分 左边都小于基准数 右边都大于基准数 然后我们只需要分别对左右两个序列快速排序即可
接来下 我们给出代码: