快速排序作为一种高效的排序算法被广泛应用,SUN的JDK中的Arrays.sort 方法用的就是快排。

快排采用了经典的分治思想(divide and conquer):

Divide:选取一个基元X(一般选取数组第一个元素),通过某种分区操作(partitioning)将数组划分为两个部分:左半部分小于等于X,右半部分大于等于X。

Conquer: 左右两个子数组递归地调用Divide过程。

Combine:快排作为就地排序算法(in place sort),不需要任何合并操作

可以看出快排的核心部分就是划分过程(partitioning),下面以一个实例来详细解释如何划分数组(图取自于《算法导论》)

初始化:选取基元P=2,就是数组首元素。i=1,j=i+1=2 (数组下标以1开头)

循环不变量:2~i之间的元素都小于或等于P,i+1~j之间的元素都大于或等于P

循环过程:j从2到n,考察j位置的元素,如果大于等于P,就继续循环。如果小于P,就将j位置的元素(不应该出现在i+1~j这个区间)和i+1位置(交换之后仍在i+1~j区间)的元素交换位置,同时将i+1.这样就维持了循环不变量(见上述循环不变量说明)。直到j=n,完成最后一次循环操作。

要注意的是在完成循环后,还需要将i位置的元素和数组首元素交换以满足我们最先设定的要求(对应图中的第i步)。

细心的读者可能会想到另一种更直白的分区方法,即将基元取出存在另一相同大小数组中,遇到比基元小的元素就存储在数组左半部分,遇到比基元大的元素就存储在数组右半部分。这样的操作复杂度也是线性的,即Theta(n)。但是空间复杂度提高了一倍。这也是快排就地排序的优势所在。

最后附上快排的java代码实现:

public class QuickSort {

    private static void QuickSort(int[] array,int start,int end)
{
if(start<end)
{
int key=array[start];//初始化保存基元
int i=start,j;//初始化i,j
for(j=start+1;j<=end;j++)
{
if(array[j]<key)//如果此处元素小于基元,则把此元素和i+1处元素交换,并将i加1,如大于或等于基元则继续循环
{
int temp=array[j];
array[j]=array[i+1];
array[i+1]=temp;
i++;
} }
array[start]=array[i];//交换i处元素和基元
array[i]=key;
QuickSort(array, start, i-1);//递归调用
QuickSort(array, i+1, end); } }
public static void main(String[] args)
{
int[] array=new int[]{11,213,134,44,77,78,23,43};
QuickSort(array, 0, array.length-1);
for(int i=0;i<array.length;i++)
{
System.out.println((i+1)+"th:"+array[i]);
}
}
}

以下是运行结果:

快速排序详解以及java实现的更多相关文章

  1. 事件驱动模型实例详解(Java篇)

    或许每个软件从业者都有从学习控制台应用程序到学习可视化编程的转变过程,控制台应用程序的优点在于可以方便的练习某个语言的语法和开发习惯(如.net和java),而可视化编程的学习又可以非常方便开发出各类 ...

  2. 快速排序详解(C语言/python)

    快速排序详解 介绍: 快速排序于C. A. R. Hoare在1960年提出,是针对冒泡排序的一种改进.它每一次将需要排序的部分划分为俩个独立的部分,其中一个部分的数比的数都小.然后再按照这个方法对这 ...

  3. Heapsort 堆排序算法详解(Java实现)

    Heapsort (堆排序)是最经典的排序算法之一,在google或者百度中搜一下可以搜到很多非常详细的解析.同样好的排序算法还有quicksort(快速排序)和merge sort(归并排序),选择 ...

  4. Myeclipse Templates详解(一) —— Java模板基础

    目录 Templates简介 MyEclipse自带Templates详解 新建Template 自定义Template 因为自己比较懒,尤其是对敲重复代码比较厌恶,所以经常喜欢用快捷键和模板,Mye ...

  5. 二叉搜索树详解(Java实现)

    1.二叉搜索树定义 二叉搜索树,是指一棵空树或者具有下列性质的二叉树: 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值: 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根 ...

  6. Java AtomicInteger类的使用方法详解_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 首先看两段代码,一段是Integer的,一段是AtomicInteger的,为以下: public class Samp ...

  7. java 流操作对文件的分割和合并的实例详解_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 java 流操作对文件的分割和合并的实例详解 学习文件的输入输出流,自己做一个小的示例,对文件进行分割和合并. 下面是代 ...

  8. springboot扫描自定义的servlet和filter代码详解_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 这几天使用spring boot编写公司一个应用,在编写了一个filter,用于指定编码的filter,如下: /** ...

  9. java快速排序详解

    快速排序 public class QuickSort { public static void main(String[] args) { int[] a = { 0, 3, 6, 8, 2, 4, ...

随机推荐

  1. 清除Xcode缓存和存档文件

    XCode4.2    finder中找到   /Users/Library/Developer/Xcode    (注:Library资源库是隐藏的文件夹) 里面有DerivedData和Snaps ...

  2. [Everyday Mathematic]20150217

    设 $f:\bbR\to\bbR$ 二阶可微, 适合 $f(0)=1$, $f'(0)=0$, 并且 $$\bex f''(x)-5f'(x)+6f(x)\geq 0. \eex$$ 试证: $$\b ...

  3. 组合 z

    输入a b c d e以及它们对应的数字 比如 a-->1 2 3  b-->2 3 c-->1 d-->3 4 5 e-->1 3 5 输出a b c d e的可用组合 ...

  4. python+selenium环境搭建

    这里主要基于windows平台. 下载python.http://python.org/getit/ 下载setuptools [python的基础包工具].http://pypi.python.or ...

  5. 图Graph

    存储结构: 1.邻接矩阵存储 typedef struct { char vex[MAXVEX];//顶点数 int arc[MAXVEX][MAXVEX];//邻接矩阵 int numVextexe ...

  6. 虚幻4以及DX12将允许开发者利用Xbox One的更多性能(转)

    GamingBolt 最近采访了 Epic Games 的总经理 Ray Davis,讨论了有关旗下虚幻引擎(Unreal Engine)的议题.在这次的访谈中,Ray 解释了关于使用 DirectX ...

  7. linux(centos7)下安装tomcat7

    1.下载tomcat1.7.tar.gz 2.将文件放到/usr/local中 #cp tomcat1.7.tar.gz /usr/local 3.进入到/usr/local中,解压缩tomcat1. ...

  8. 【LeetCode】139 - Word Break

    Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separa ...

  9. 数往知来 ADO.NET <八>

    ADO.NET基础 学习目的:通过程序访问数据库 ,ADO.NET就是一组类库, -->connection   用来连接数据库的类 语法:首先需要一个连接字符串 -->以SQL serv ...

  10. effective c++:private继承

    如果class间使用private继承关系,编译器就不会自动的将派生类转换为基类,而且private继承而来的成员都变为private属性. private继承意味着根据某物实现出,当我们想要避免重复 ...