目录

  • 一、 快速排序基准位置的选取方法
    • 1.固定位置法
    • 2.随机选取基准法
    • 3、三分取基准
  • 二、优化:
    • 1、当待排序数组当中数据比较少的时候,用直插
    • 2、聚集相同元素法(基准一样的元素),减少递归的次数

一、 快速排序基准位置的选取方法

1.固定位置法

参考代码

(就是选取的基准是固定的、一般是数组的第一个元素)
这种方法的缺点是当给定的序列本身有序的时候快速排序就退化成了冒泡排序,效率很低;

2.随机选取基准法

import java.util.Arrays;
import java.util.Random;/*** @ClassName TestDemo3* @Description 快速排序,随机选取基准法* @Author lzq* @Date 2018/10/27 22:24* @Version 1.0**/
public class TestDemo3 {public static void main(String[] args) {int[] array = {20,1,9,56,25,32,87,45,12,69,54,19,98,51,25};quickSort(array);System.out.println(Arrays.toString(array));}/*** 快速排序* @param array*/public static void quickSort(int[] array) {if(array == null || array.length == 0) {return;}sort(array,0,array.length-1);}/*** 递归的排序数据* @param array* @param start* @param end*/private static void sort(int[] array,int start,int end) {Random random = new Random();int x = random.nextInt(end-start+1)+start;//产生在start到end之间的随机数swap(array,start,x);int once = once(array,start,end);if(once > start+1) {  //排序左边sort(array,start,once-1);}if(once < end-1) {  //排序右边sort(array,once+1,end);}}/*** 一趟快速排序* @param array* @param start* @param end* @return*/private static int once(int[] array,int start,int end) {int tmp = array[start];while(start < end) {while(start < end && array[end] >= tmp) {--end;}array[start] =  array[end];  //把比基准tmp大的数字移到后面while(start < end && array[start] <= tmp) {++start;}array[end] = array[start];  //把比基准tmp小的数字移到前面}array[start] = tmp;   //把基准放在它该放的位置return start;    //返回基准的位置,后面分别在这个基准位置两边重复上面的操作}/*** 将产生的随机下标与start下标交换,而这个新的array[start]会为成为后面比较* 的基准,这样就达到了,随机选取基准的目的* @param array* @param start* @param end*/public static void swap(int[] array,int start,int end) {int tmp = array[start];array[start] = array[end];array[end] = tmp;}}

3、三分取基准

这个方法也就是把数组的第一个最后一个和最中间的元素拿出来比较一下,把三者中最大的放最后面,最小的放最中间面,剩下那个元素放前面(原因是无论是哪种取基的方法,最终用的还是固定位置法,也就是还是要拿首部的数据开始进行比较调整!)。然后在用递归的方式比较排序:

import java.util.Arrays;
/*** @ClassName TestDemo4* @Description 快速排序——三分取基法* @Author lzq* @Date 2018/10/27 22:33* @Version 1.0**/
public class TestDemo4 {public static void main(String[] args) {int[] array = {20,23,98,54,12,15,0,19,3,46,78,59,84};System.out.println("原数组"+Arrays.toString(array));quickSort(array);System.out.println("排序后数组:"+Arrays.toString(array));}/*** 快速排序* @param array*/public static void quickSort(int[] array) {if(array == null || array.length == 0) {return;}sort(array,0,array.length-1);}/*** 三分取基* 调整位置* 使最大的数据在最后面,最小数据的在中间,剩下的那个在最前面* @param array* @param low* @param high*/public static void new_sort(int[] array,int low,int high) {int mid = low+(high-low)/2;if(array[mid] > array[low]) {swap(array,mid,low);}if(array[low] > array[high]) {swap(array,low,high);}if(array[mid] > array[high]) {swap(array,mid,high);}System.out.println("三分取基后:"+Arrays.toString(array));}/*** 交换数组元素位置* @param array* @param start* @param end*/public static void swap(int [] array ,int start,int end) {int temp = array[start];array[start] = array[end];array[end] = temp;}/*** 递归的排序数据* @param array* @param start* @param end*/private static void sort(int[] array,int start,int end) {new_sort(array,start,end);int once = once(array,start,end);if(once > start+1) {  //排序左边sort(array,start,once-1);}if(once < end-1) {  //排序右边sort(array,once+1,end);}}/*** 一趟快速排序* @param array* @param start* @param end* @return*/private static int once(int[] array,int start,int end) {int tmp = array[start];while(start < end) {while(start < end && array[end] >= tmp) {--end;}array[start] =  array[end];  //把比基准tmp大的数字移到后面while(start < end && array[start] <= tmp) {++start;}array[end] = array[start];  //把比基准tmp小的数字移到前面}array[start] = tmp;   //把基准放在它该放的位置return start;        //返回基准的位置,后面分别在这个基准位置两边重复上面的操作}
}

运行结果:

原数组[20, 23, 98, 54, 12, 15, 0, 19, 3, 46, 78, 59, 84]
三分取基后:[20, 23, 98, 54, 12, 15, 0, 19, 3, 46, 78, 59, 84]
三分取基后:[3, 19, 0, 15, 12, 20, 54, 98, 23, 46, 78, 59, 84]
三分取基后:[0, 3, 12, 15, 19, 20, 54, 98, 23, 46, 78, 59, 84]
三分取基后:[0, 3, 12, 15, 19, 20, 54, 98, 23, 46, 78, 59, 84]
三分取基后:[0, 3, 12, 15, 19, 20, 54, 98, 23, 46, 78, 59, 84]
三分取基后:[0, 3, 12, 15, 19, 20, 23, 46, 54, 98, 78, 59, 84]
三分取基后:[0, 3, 12, 15, 19, 20, 23, 46, 54, 84, 78, 59, 98]
三分取基后:[0, 3, 12, 15, 19, 20, 23, 46, 54, 59, 78, 84, 98]
排序后数组:[0, 3, 12, 15, 19, 20, 23, 46, 54, 59, 78, 84, 98]

二、优化:

1、当待排序数组当中数据比较少的时候,用直插

import java.util.Arrays;/*** @ClassName TestDemo1* @Description 快速排序的优化* @Author lzq* @Date 2018/10/27 21:24* @Version 1.0**/
public class TestDemo1 {public static void main(String[] args) {int[] array = {20,1,9,56,25,32,87,45,12,69,54,19};System.out.println(Arrays.toString(array));quickSort(array);System.out.println(Arrays.toString(array));}/*** 快速排序* @param array*/public static void quickSort(int[] array) {if(array == null || array.length == 0) {return;}sort(array,0,array.length-1);}/*** 递归的排序数据* @param array* @param start* @param end*/private static void sort(int[] array,int start,int end) {if(end-start <= 100) {insert_Sort(array,start,end); //数据不多,用直接插入排序return;}else {int once = once(array, start, end);if (once > start+1) {  //排序左边sort(array, start, once - 1);}if (once < end-1) {  //排序右边sort(array, once + 1, end);}}}/*** 给给定区间数据进行插入排序* @param array* @param low* @param high*/public static void insert_Sort(int[] array,int low,int high) {int j = 0,temp = 0;for(int i = low+1;i <= high;i++) {temp = array[i];for(j = i-1;j >= low;j--) {if(array[j] > temp) {array[j+1] = array[j];}else {break;}}array[j+1] = temp;}}/*** 一趟快速排序* @param array* @param start* @param end* @return*/private static int once(int[] array,int start,int end) {int tmp = array[start];while(start < end) {while(start < end && array[end] >= tmp) {--end;}array[start] =  array[end];  //把比基准tmp大的数字移到后面while(start < end && array[start] <= tmp) {++start;}array[end] = array[start];  //把比基准tmp小的数字移到前面}array[start] = tmp;   //把基准放在它该放的位置return start;        //返回基准的位置,后面分别在这个基准位置两边重复上面的操作}
}

2、聚集相同元素法(基准一样的元素),减少递归的次数

当i和j遍历完后,也就把相同元素聚集完了,

这时,下一次基准的左右两边再次递归排序时,就不是这次基准位置的两边了,而是left的左边和right的右边。

import java.util.Arrays;/*** @ClassName TestDemo5* @Description 聚集相同元素法* @Author lzq* @Date 2018/10/27 22:47* @Version 1.0**/
public class TestDemo5 {public static void main(String[] args) {int[] array = {3,9,10,2,10,10,10,12,11,10,10,13};quickSort(array);System.out.println(Arrays.toString(array));}/*** 快速排序* @param array*/private static void quickSort(int[] array) {if(array == null || array.length == 0) {return;}sort(array,0,array.length-1);}/*** 交换数组中两个元素的位置* @param array* @param low* @param high*/public static void swap(int[] array,int low,int high) {int temp = array[low];array[low] = array[high];array[high] = temp;}/*** 一趟快排* 确定一个基准,把小于基准的数据移到前面去,大于基准的移到后面,确定基准的位置* @param array* @param low* @param high* @return*/public static int partion(int[] array,int low,int high) {int temp = array[low];while(low < high) {while(low < high && array[high] > temp) {--high;}array[low] = array[high];while(low < high && array[low] <= temp) {++low;}array[high] = array[low];}array[low] = temp;return low;}/*** 递归的排序数据* @param array* @param start* @param end*/private static void sort(int[] array,int start,int end) {int par = partion(array,start,end);int[] element = focusParNum(array,par,start,end);if(element[0] > start+1) {  //排序左边sort(array,start,element[0]);}if(element[1] < end-1) {  //排序右边sort(array,element[1],end);}}/*** 聚集相同元素* @param array* @param par* @param start* @param end* @return*/private static int[] focusParNum(int[] array, int par,int start,int end) {int left = par-1;int right = par+1;/*** 聚集左边*/for(int i = par-1;i >= start;i--) {if(array[i] == array[par]) {if(i != left) {swap(array, left, i);left--;}else {left--;}}}/*** 聚集右边*/for(int i = par+1;i <= end;i++) {if(array[i] == array[par]) {if(i != right) {swap(array, i, right);right--;}else {right--;}}}return new int[] {left,right};}}

运行结果:

[2, 3, 9, 10, 10, 10, 10, 10, 10, 11, 12, 13]

快速排序基准位置的选取方法和快速排序优化相关推荐

  1. C++十种排序方法(快速排序、冒泡排序等等)

    C++十种排序方法(快速排序.冒泡排序等等) 一.冒泡排序 1.概念及思路:冒泡排序顾名思义就是大的数沉下去,小的数浮上来,就跟气泡在水底浮上来一样:基本的思路很简单,就是相邻的两个数相比较,如果前面 ...

  2. 快速排序的两种实现方法(c语言版本)

    经过调研发现,对任意无序整数数组,快速排序有两种实现方法,这里简单阐述下思路: 思路一:随意选择一个基准元,一般选择数组的起始元或末尾元,Weiss这本书上特意搞了个算法来选择基准元,--,总之就是基 ...

  3. php 快速排序函数,PHP实现快速排序算法的三种方法

    摘要:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序 ...

  4. ReviewForJob——快速排序(基于插入排序)+快速选择(快速排序变体)

    [0]README 0)本文旨在给出 快速排序 的 源码实现和源码分析(分析它的坑): 2)要知道 在 元素个数小于10的时候,快速排序不如插入排序:注意快速排序选取枢纽元 时 所使用的方法是 三数中 ...

  5. 快速排序算法_基于位运算的快速排序算法

    前言 如果你准备看这篇文章,我就当你是懂快速排序算法原理的. 下面是我在2018年10月3日想到的基于二进制位运算对正整数进行的一种快速排序算法,目前的代码只能对正整数进行有效的排序,当然,稍微修改一 ...

  6. Creo 9.0 中几何对象的选取方法

    在草绘或进行特征编辑操作时,经常需要选取几何对象.例如,选中曲线后,可对其进行删除操作,也可对线条进行拖动修改等.快速有效地选取对象,可以提升建模效率. 1.几何对象常见的选取方式 Creo 9.0中 ...

  7. jQuery选择器和选取方法 http://www.cnblogs.com/MaxIE/p/4078869.html

    我们已经使用了带有简单Css选择器的jQuery选取函数:$().现在是时候深入了解jQuery选择器语法,以及一些提取和扩充选中元素集的方法了. 一.jQuery选择器 在CSS3选择器标淮草案定义 ...

  8. jQuery选择器和选取方法

    我们已经使用了带有简单Css选择器的jQuery选取函数:$().现在是时候深入了解jQuery选择器语法,以及一些提取和扩充选中元素集的方法了. 一.jQuery选择器 在CSS3选择器标淮草案定义 ...

  9. Matlab 矩阵元素选取方法

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 1.简单切片 2.根据条件选取 3.根据下标选取对应元素 1)简介 2)二维选取 3)多维选取 总结 前言 提示:这里 ...

最新文章

  1. mybatis中useGeneratedKeys用法--插入数据库后获取主键值
  2. 基于Centos7.2搭建Cobbler自动化批量部署操作系统服务
  3. 打印一个整数二进制表示中所有的奇数位和偶数位
  4. python发邮件脚本_Python实现的简单发送邮件脚本分享
  5. oracle 客户端安装包下载地址,Oracle客户端安装及下载地址
  6. 计算机专业考研复试个人简介ppt,蓝色简约考研复试个人简历通用ppt.pptx
  7. 中州韵输入法 linux 小鹤双拼,「Rime 鼠须管」小鹤双拼配置指南
  8. ViewPage详解
  9. jquery的keyup()事件案列——根据输入中文名称自动显示添加对应的拼音简写+时间戳
  10. 登录中国人民银行征信中心
  11. spark学习系列——6 Historyserver配置
  12. 【JavaSE】多线程基础
  13. 大数据工作流开源系统之DRAKE
  14. UHF超高频RFID纸质电子标签与树莓派通信
  15. 揽月摘星 | 第 13 届金鼠标数字营销大赛得奖名单出炉,知家斩获 5 项大奖
  16. 使用计算机的快捷键有哪些,电脑操作的快捷键有哪些,都是什么作用?
  17. er图的好处_如何把ER模型转换为关系模型(超详细,含例题)
  18. 怎么解决app下载链接被微信屏蔽拦截导致打开显示已停止访问该网页问题?
  19. 最新消息: 阿桑奇的猫是安全的
  20. 3dmax中如何制作汽车的行走动画

热门文章

  1. AOP框架Aspects原理解析
  2. 为什么越来越多的企业开始注重专利权?
  3. 〖Python自动化办公篇⑮〗- PPT 文件自动化 - 创建 PPT 文件(9种样式)
  4. 在网上搜索想要的答案的好技巧
  5. 计算机基础知识—数据库
  6. 二维前缀和(矩形割补法)——杨子曰算法
  7. 关于移动互联网产品的指标分析初探
  8. PostgreSQL学习手册(函数和操作符二)
  9. 分享167个PHP源码,总有一款适合您
  10. 【codevs3369】膜拜