快速排序基本思想
输入代排数组——>选取基准元——>执行划分操作——>递归对两个数组进行快速排序
1、比如这里输入序列{72,6,57,88,60,42,83,73,48}
2、下面选取基准元,这里选取72

选取基准元后,会用另一个空间存放基准元的数据,用两个指针分别指向数组最前端与最后端,从最后端开始比较,如果比基准元72小,则放在基准元前面,也就是将数据放在前端指针指的数据,这里是48<72所以要放在第一个位置。
3、执行划分操作

再移动前端指针,依次进行数据的改变,当前后指针指向同一个数据时,就是划分结束,将基准元的数据放在指针的位置。

4、递归对两个数组进行快速排序

现在依据第一次的基准元,将数组分为左右两个部分,分别对两个数组进行快速排序,基准元选择第一个数字,也就是48、83作为基准元。

执行划分后得到上图,依次类推执行快速排序。

经过三次划分后,得到了有序的序列。
快速排序优化方法
选择基准的方式——固定位置
思想:取待排序列的第一个或最后一个作为基准
就是我们刚才举列子的方式,这种方式在最好的情况下,时间复杂度是O(nlgn),不过在最坏情况下,也就是这个序列本身是有序的时候,这个排序就会变成冒泡排序,时间复杂度为O(n2)

选择基准的方式——随机选择基准
思想:取待排序列中的任意一个作为基准
简单分析:
基准元的位置是随机的,则出现最坏情况的概率大大降低,最好情况依然是O(nlgn)
在整个数组数字全相等时,仍然是 最坏情况,时间复杂度是O(n2)
选择基准的方式——“三数取中”选取基准元

这样可以尽可能让划分得到的两个序列尽可能等长,会降低快速排序的时间复杂度。
快速排序+插入排序
原因:
对于很小和部分有序的数组,快排不如插排好
“聚key”方法
思想:在一次分割结束后,可以把与Key相等的元素聚在一起,继续下次分割时,不用再对与key相等元素分割。
这里给出序列{1,4,6,7,6,6,7,6,8,6},

用三数取中的方法会选择出基准元6,最后划分出左右两个子序列。

这个方法与其他方法的不同,就是在移动指针时,如果指针的值,和基准元一样,比如这里指向6,那就会将这个数移动到两端(哪一边的指针指向的,就移动到哪一段)。

再将两端的key值,移动到与基准相等的地方,最后划分得到左右两个子序列。

采用这种方法,能减少迭代次数,提高效率。
快排及其优化-总结

在优化方面,主要集中在选取基准元和执行划分操作上。
网友评论