排序算法(四)——快速排序
来源:互联网 发布:阿里云 七牛云 直播 编辑:程序博客网 时间:2024/06/01 08:23
排序
快速排序:
1.使用第一个记录的关键码;2.选取序列中间记录的关键码;3.比较序列中第一个记录、最后一个记录和中间记录的关键码,取关键码居中的作为轴值并调换到第一个记录的位置;4.随机选取轴值。
轴值的选择将决定两个子序列的长度,子序列的长度最好相等。这里笔者选择第一个记录作为轴值。
一次划分:对待排序列进行一次划分的过程。
设待划分的序列是r[s] ~ r[t],设参数i,j分别指向子序列左、右两端的下标s和t,令r[s]为轴值,
(1)j从后向前扫描(找小),直到r[j]<r[i],将r[j]移动到r[i]的位置,使关键码小(同轴值比较)的记录移动到前面去;
(2)i从前向后扫描(找大),直到r[i]>r[j],将r[i]移动到r[j]的位置,使关键码大(同轴值比较)的记录移动到后面去;
(3)重复上述过程,直到i=j。
一次划分如图
看看具体过程:
快速排序 进行划分
/*
* first end 分别指向待划分区间的最左侧记录和最右侧记录
* ① 初始化 第一个记录为轴值
* ② 右侧扫描 从end向前扫,直到扫描到小于轴值的记录后交换,此时轴值交换到了end所指的位置。
* ③ 左侧扫描 从first想后扫,知道扫描到了大于轴值的记录后交换,此时轴值交换到了first所指的位置。
* ④ 重复 ② ③ 过程直到 first 和 end 相遇,并返回相遇位置(轴值最终位置)
*/
private int partition(T[] t, int first, int end){while(first < end){ //右侧扫描 : 将轴值与end指向的记录进行比较。若end大,则end 前移一个位置,直到end小于轴值while(first < end && compare(t[first], t[end])){ end--; }if(first < end){T tmp = t[end]; //小的记录移到前面, 交换后轴值为end指向的记录。t[end] = t[first];t[first] = tmp;first ++;}//左侧扫描 :将轴值与first指向的记录比较。若first小,则 first前移一个位置,直到first大于轴值while(first < end && compare(t[first], t[end])){ first ++;}if(first < end){T tmp = t[end]; // 大的记录移到后面,交换后轴值又为first指向的记录t[end] = t[first];t[first] = tmp;end --;}}return first;}
递归过程:快速排序是一个递归的过程,需要不断对子序列进行划分,直到每个序列都为有序序列。
private void sort(T[] t, int first, int end){if(first < end){ //区间长度大于1,执行一次划分,否则递归结束。int center = partition(t, first, end); //一次划分sort(t, first, center -1); // 递归地对左侧子序列进行快速排序sort(t, center +1, end);<span style="white-space:pre"></span> //递归地对右侧子序列进行快速排序}}
快速排序主入口:
/** * 交换排序: 快速排序 */@Overridepublic void quickSort(T[] t) {if(t.length > 0){sort(t, 0, t.length -1);}System.out.println("快速排序:");print(t);}
上面的compare 、 print 方法将在讲解完全部排序介绍,这里仍然才用泛型。
性能分析: 快速排序的趟数取决于递归的深度。
(1)在最好情况下,每一次划分对一个记录定位后,该记录的左侧子表与右侧子表的长度相同,时间复杂度为O(nlog2n)。对n个记录的序列进行排序的时间,每次划分后,正好把待划分区间划分成长度相等的两个子序列。
(2)在最坏情况下,待排序列为正序或者逆序。每次划分只得到一个比上一次划分少一个记录的子序列(另一个子序列为空),时间复杂度为 O(N*N)。
(3)平均情况下,由于给出的序列一般都是乱序的,很少情况出现正序或者逆序,所以平均性能的数量级也是O(nlog2n)。
稳定性:
若两个记录A和B值相等,但是排序后A、B的先后次序保持不变,则这种排序是稳定的,否则就是不稳定。快速排序是一种不稳定的排序算法。
总结:
(1)由于快速排序是递归的,需要一个栈来存放每一层递归调用的信息,其容量与递归调用的深度一致,平均深度为:O(logN)。
(2)快速排序是一种不稳定的排序算法。
(3)快速排序适用于待排记录个数很大并且原始记录随机(这也是数据的主要情况:多、乱)。
(4)快速排序的平均性能很好。
- 排序算法(四)——快速排序
- 算法——排序(四)快速排序
- 排序算法(四)快速排序算法
- 排序算法(四):快速排序
- 排序算法(四)-- 快速排序
- Java排序算法(四):快速排序
- 快速排序----(排序算法四)
- 排序算法(四):快速排序
- 基础算法系列(四)——快速排序
- 排序算法—快速排序
- 排序算法—快速排序
- 使用快速排序算法对列表进行排序——Leetcode系列(四)
- 重新教自己学算法之递归排序——快速排序(四)
- 小白学数据结构——四、排序算法Python(冒泡、选择、快速、插入、希尔、归并排序)
- 排序算法(2)—归并排序,快速排序
- 算法导论排序算法之快速排序(四)
- (四)算法--排序算法分治 快速排序
- 算法学习(四)----快速排序
- Coredump故障分析
- 04环信聊天界面 - 完善语音消息在cell上的显示
- 11.Oracle深度学习笔记——操作系统自动化监控脚本
- 源代码管理器git
- python列表删除会出现一个错误 list index out of range
- 排序算法(四)——快速排序
- 总结学习Fckeditor使用方法
- C++基础篇之 复制构造函数调用时机
- tableView中实现headView图片拉伸效果的三种解决方案
- 我的C#学习日记:2016.2.19
- Spark MLlib 1.6 -- 数据类型篇
- windows基础知识----第一篇(项目的创建)
- Ionic 上拉刷新,下拉加载
- Vert.x 3学习笔记---01