快排概念

快速排序(英语:Quicksort),又称划分交换排序(partition-exchange sort),一种排序算法,最早由东尼·霍尔提出。在平均状况下,排序个项目要(大O符号)次比较。在最坏状况下则需要次比较,但这种状况并不常见。事实上,快速排序通常明显比其他算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。

实现思想

快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。

步骤为:

  1. 从数列中挑出一个元素,称为"基准"(pivot),
  2. 重新排序数列,所有比基准值小的元素摆放在基准前面,所有比基准值大的元素摆在基准后面(相同的数可以到任何一边)。在这个分区结束之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
  3. 递归地(recursively)把小于基准值元素的子数列和大于基准值元素的子数列排序。

递归到最底部时,数列的大小是零或一,也就是已经排序好了。这个算法一定会结束,因为在每次的迭代(iteration)中,它至少会把一个元素摆到它最后的位置去。

借用下啊哈算法的图:

i和j分别为左哨兵和右哨兵,这里枢纽元定为6,然后分别从左往右(i++)和右往左(j--)开始遍历

左哨兵查找比6大的元素,右哨兵查找比6小的元素

第一次交换结果

第二次交换结果

相遇后直接与枢纽元交换

然后再递归排序就行


快排核心算法代码

  1. public static <T extends Comparable<? super T>> void quicksort(T[] a,int left,int right) {
  2. /*
  3. * 当数组不小于3时,才推荐使用快排
  4. * */
  5. if(left+CUTOFF<=right)
  6. {
  7. //取出枢纽元,枢纽元的位置为right-1
  8. T privot=median3(a, left, right);
  9.  
  10. int i=left,j=right-1;
  11. for(;;)
  12. {
  13. while(a[++i].compareTo(privot)<0) {}//i哨兵向右遍历
  14. while(a[--j].compareTo(privot)>0) {}//j哨兵向左遍历
  15. if(i<j)
  16. swapReferences(a, i, j);
  17. else
  18. break;
  19. }
  20. /*
  21. * for循环终止条件为i和j相遇,此时再将枢纽元归位
  22. * */
  23. swapReferences(a, i, right-1);
  24.  
  25. quicksort(a, left, i-1);//对左半部进行递归
  26. quicksort(a, i+1, right);//对右半部进行递归
  27. }
  28. else
  29. {}
  30. }

全部代码实现

  1. public class MyQuickSort {
  2. private static final int CUTOFF=3;
  3. public static <T extends Comparable<? super T>> void quicksort(T[] a) {
  4. quicksort(a,0,a.length-1);
  5. }
  6. public static <T extends Comparable<? super T>> void quicksort(T[] a,int left,int right) {
  7. /*
  8. * 当数组不小于3时,才推荐使用快排
  9. * */
  10. if(left+CUTOFF<=right)
  11. {
  12. //取出枢纽元,枢纽元的位置为right-1
  13. T privot=median3(a, left, right);
  14.  
  15. int i=left,j=right-1;
  16. for(;;)
  17. {
  18. while(a[++i].compareTo(privot)<0) {}//i哨兵向右遍历
  19. while(a[--j].compareTo(privot)>0) {}//j哨兵向左遍历
  20. if(i<j)
  21. swapReferences(a, i, j);
  22. else
  23. break;
  24. }
  25. /*
  26. * for循环终止条件为i和j相遇,此时再将枢纽元归位
  27. * */
  28. swapReferences(a, i, right-1);
  29.  
  30. quicksort(a, left, i-1);//对左半部进行递归
  31. quicksort(a, i+1, right);//对右半部进行递归
  32. }
  33. else
  34. {}
  35. }
  36. /*
  37. * 数组中数值交换
  38. * */
  39. public static <T> void swapReferences(T[] a,int index1,int index2) {
  40. T tmp=a[index1];
  41. a[index1]=a[index2];
  42. a[index2]=tmp;
  43. }
  44. /*
  45. * 确定枢纽元,枢纽元的位置放在right-1位置
  46. * */
  47. private static <T extends Comparable<? super T>> T median3(T[] a,int left,int right) {
  48. int center=(left+right)/2;
  49. if(a[center].compareTo(a[left])<0)
  50. swapReferences(a, left, center);
  51. if(a[right].compareTo(a[center])<0)
  52. swapReferences(a, center, right);
  53. if(a[right].compareTo(a[left])<0)
  54. swapReferences(a, left, right);
  55.  
  56. swapReferences(a, center, right-1);
  57. return a[right-1];
  58. }
  59. }

JAVA数据结构--快速排序的更多相关文章

  1. Java数据结构和算法(五)--希尔排序和快速排序

    在前面复习了三个简单排序Java数据结构和算法(三)--三大排序--冒泡.选择.插入排序,属于算法的基础,但是效率是偏低的,所以现在 学习高级排序 插入排序存在的问题: 插入排序在逻辑把数据分为两部分 ...

  2. Java数据结构之树和二叉树(2)

    从这里始将要继续进行Java数据结构的相关讲解,Are you ready?Let's go~~ Java中的数据结构模型可以分为一下几部分: 1.线性结构 2.树形结构 3.图形或者网状结构 接下来 ...

  3. Java数据结构和算法(九)——高级排序

    春晚好看吗?不存在的!!! 在Java数据结构和算法(三)——冒泡.选择.插入排序算法中我们介绍了三种简单的排序算法,它们的时间复杂度大O表示法都是O(N2),如果数据量少,我们还能忍受,但是数据量大 ...

  4. Java数据结构和算法 - 堆

    堆的介绍 Q: 什么是堆? A: 这里的“堆”是指一种特殊的二叉树,不要和Java.C/C++等编程语言里的“堆”混淆,后者指的是程序员用new能得到的计算机内存的可用部分 A: 堆是有如下特点的二叉 ...

  5. Java数据结构和算法 - 高级排序

    希尔排序 Q: 什么是希尔排序? A: 希尔排序因计算机科学家Donald L.Shell而得名,他在1959年发现了希尔排序算法. A: 希尔排序基于插入排序,但是增加了一个新的特性,大大地提高了插 ...

  6. Java数据结构与算法 - 外部存储

    Q: 什么是外部存储? A: 外部存储特指某类磁盘系统,例如在大多数台式电脑或服务器中的硬盘. Q: 如何访问外部存储? A: 我们所学的数据结构都是假设数据存储在内存中,但是,在很多情况下要处理的数 ...

  7. Java数据结构和算法(五)二叉排序树(BST)

    Java数据结构和算法(五)二叉排序树(BST) 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 二叉排序树(Binary S ...

  8. Java数据结构和算法(四)赫夫曼树

    Java数据结构和算法(四)赫夫曼树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 赫夫曼树又称为最优二叉树,赫夫曼树的一个 ...

  9. Java数据结构和算法(三)--三大排序--冒泡、选择、插入排序

    三大排序在我们刚开始学习编程的时候就接触过,也是刚开始工作笔试会遇到的,后续也会学习希尔.快速排序,这里顺便复习一下 冒泡排序: 步骤: 1.从首位开始,比较首位和右边的索引 2.如果当前位置比右边的 ...

随机推荐

  1. vim调用替换文件内容

    :s/vivian/sky/ 替换当前行第一个 vivian 为 sky    :s/vivian/sky/g 替换当前行所有 vivian 为 sky    :n,$s/vivian/sky/ 替换 ...

  2. Linux网络配置之虚拟网卡的配置(ubuntu 16.04)

    关于图形界面的配置,我这里就不多介绍了,这个很简单.这里介绍的是如何通过修改配置文件来实现虚拟网卡. 首先介绍ubuntu(我这里使用的是ubuntu-16.04)下虚拟网卡的配置 1.先用ifcon ...

  3. linux tomcat自动部署shell

    #!/bin/bash   #defined    TOMCAT_HOME="/usr/java/tomcat/tomcat"   TOMCAT_PORT=80   PROJECT ...

  4. Windows下如何安装MongoDB

    下载地址: http://www.mongodb.org/downloads 我下载的是:mongodb-win32-x86_64-2008plus-2.6.6 解压到:D:\soft 同时在该目录下 ...

  5. [GO]文件的收发服务器

    发送方 package main import ( "fmt" "os" "net" "io" ) //发送文件内容 f ...

  6. CodeForces 427A Police Recruits (水题)

    题意:给定 n 个数,有正数和-1, -1表示罪犯,正数表示招了几个警察,一个警察只能看一个罪犯,并且要按顺序,问你有多少罪犯逃脱. 析:很简单么,从开始扫到最后,把是正数就加上,是-1判断剩余警察大 ...

  7. Hadoop压缩之MapReduce中使用压缩

    1.压缩和输入分片 Hadoop中文件是以块的形式存储在各个DataNode节点中,假如有一个文件A要做为输入数据,给MapReduce处理,系统要做的,首先从NameNode中找到文件A存储在哪些D ...

  8. Matlab SLAM

    https://www.baidu.com/s?wd=Matlab%20SLAM&rsv_spt=1&rsv_iqid=0xfacaed5e00006d4e&issp=1&am ...

  9. 编写高质量代码改善C#程序的157个建议——建议80:用Task代替ThreadPool

    建议80:用Task代替ThreadPool ThreadPool相对于Thread来说具有很多优势,但是ThreadPool在使用上却存在一定的不方便.比如: ThreadPool不支持线程的取消. ...

  10. 编写高质量代码改善C#程序的157个建议——建议64:为循环增加Tester-Doer模式而不是将try-catch置于循环内

    建议64:为循环增加Tester-Doer模式而不是将try-catch置于循环内 如果需要在循环中引发异常,你需要特别注意,应为抛出异常是一个相当影响性能的过程.应该尽量在循环当中对异常发生的一些条 ...