随手编程---快速排序(QuickSort)-Java实现

背景

快速排序,是在上世纪60年代,由美国人东尼·霍尔提出的一种排序方法。这种排序方式,在当时已经是非常快的一种排序了。因此在命名上,才将之称为“快速排序”。这个算法是二十世纪的七大算法之一,平均情况下时间复杂度为Ο(nlogn),而且在O(nlogn)的情况下,实际的运算速度都要快于其他同时间复杂度的排序方法。

对东尼·霍尔以及快速排序的提出背景感兴趣的同学,可以看看这篇介绍:http://www.nowamagic.net/librarys/veda/detail/2391

排序思想

快速排序的思路想到很困难,但是理解起来却非常容易

他的思路是这样的:

1、先选定队列中,某一个元素为基数Value(一般选择头元素,或尾元素)。

2、将基数Value依次与所有元素比较大小。按照比较结果将元素分为两个队列A、B。一个所有元素比基数Value大,一个所有元素比基数Value小。

3、将A作为新的队列,再次选定基数,然后分成两个更小的队列

4、就这样一直将每一个小的队列无限的拆分成更小的两个队列。

5、一直到一个队列已经拆分成不能拆封为止(也就是一个元素)

6、因为队列之间的顺序都是固定的。将这些队列一次组合起来,整体的排序就算完成了。

(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )

注意这里有两个最核心的步骤,就是

1、选出Value元素,将整体队列划分成两个子队列

2、然后将子队列重新作为一个新的,整体规模比当前要小的,新的队列,进行计算,直到计算起来非常容易为止。

这两个核心步骤造就了快排天生的优势:

1、通过比较大小划分到子队列中的元素,在未来的比较过程中,这个元素的比较范围始终都停留在这个子队列中,不再做多余的比较。这使得早期的比较对后期的比较仍然有很大的影响。而类似于冒泡的排序方法,则前期很多的比较,对后期的作用非常小。这点和kmp算法很像,前期的比较尽量做到最大的利用。

2、将原有规模的队列,拆分成若干个规模小的子队列,这些子队列要(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )解决的问题与原有队列一致,只是规模变小了。这样不断的拆分,形成一种分而治之的思想。这种思想与背包算法也是不谋而合。

对于文字理解起来有困难的同学,可以看下下边这张网上经典的动态图,非常生动:

下边是java实现的代码

 1 import java.util.Arrays;
 2
 3 public class QuickSort
 4 {
 5     public static void main(String args[])
 6     {
 7         QuickSort quicksort = new QuickSort();
 8         int[] arrays = new int[]
 9         { 1, 12, 2, 13, 3, 14, 4, 15, 5, 16, 17, 17, 177, 18, 8, 8, 19 };
10         quicksort.quickSort(arrays);
11         System.out.println(Arrays.toString(arrays));
12     }
13
14     private void quickSort(int[] arrays)
15     {
16         subQuickSort(arrays, 0, arrays.length - 1);
17     }
18
19     private void subQuickSort(int[] arrays, int start, int end)
20     {
21         if (start >= end)
22         {
23             return;
24         }
25         int middleIndex = subQuickSortCore(arrays, start, end);
26         subQuickSort(arrays, start, middleIndex - 1);
27         subQuickSort(arrays, middleIndex + 1, end);
28     }
29
30     private int subQuickSortCore(int[] arrays, int start, int end)
31     {
32         int middleValue = arrays[start];
33         while (start < end)
34         {
35             while (arrays[end] >= middleValue && start < end)
36             {
37                 end--;
38             }
39             arrays[start] = arrays[end];
40             while (arrays[start] <= middleValue && start < end)
41             {
42                 start++;
43             }
44             arrays[end] = arrays[start];
45         }
46         arrays[start] = middleValue;
47         return start;
48     }
49 }
时间: 2024-10-15 13:38:19

随手编程---快速排序(QuickSort)-Java实现的相关文章

编程算法 - 快速排序(QuickSort)和二分查找(BinarySearch)

快速排序(QuickSort)和二分查找(BinarySearch) 本文地址: http://blog.csdn.net/caroline_wendy 快速排序和二分查找的定义, 网上书上都有, 本文主要是讲解如何写出这两个经典算法. 程序员必须掌握的两种算法, 使用任何语言, 使用纸都是必须的. 快速排序(C): /* * main.cpp * * Created on: 2014年9月10日 * Author: Spike */ #include <stdio.h> #include &

排序算法四:快速排序(Quicksort)

快速排序(Quicksort),因其排序之快而得名,虽然Ta的平均时间复杂度也是o(nlgn),但是从后续仿真结果看,TA要比归并排序和堆排序都要快. 快速排序也用到了分治思想. (一)算法实现 1 protected void quicksort(int[] array, int first, int last) { 2 3 int pivot = array[first]; 4 int i = first; 5 int j = last - 1; 6 boolean serachBig =

快速排序QuickSort

前几天实现了直接插入排序.冒泡排序和直接选择排序这三个基础排序.今天看了一下冒泡排序的改进算法,快速排序.单独记录一下,后面还有归并和基数排序等 快速排序 1.选择一个支点默认为数组第一个元素及array[start]作为支点,将所有大于支点元素的值放到支点后面,将所有小于支点元素的值放到支点前面,完成一次划分,返回支点的位置index 2.通过一个划分形成两个带排序的序列,[start, index - 1]和[index + 1, end]两个,在执行1直到序列元素只有1个则已经完成排序 具

快速排序的Java实现

快速排序(Quicksort)是对冒泡排序的一种改进. 快速排序由C. A. R. Hoare在1962年提出.它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. 下面是快速排序的Java实现: package com.newtouch.data.sort; import com.newtouch.data.test.SortTes

《编程导论(Java)&amp;#183;3.3.2 按值传递语义》

不要受<Java编程思想>的影响,计算机科学中的术语--按引用传递(pass-by-reference).不要搞成自说自话的个人用语. 这些术语也不是专门针对Java的,你不应该从某一本Java书上学习 不可以用于C.C++或Fortran语言的 特殊的"按引用传递". 验证按值传递很easy.在方法体中使用一个赋值语句,将形參作为左值. 按值传递时,对形參的赋值,不会影响实參.也就是说.那个赋值语句不会有不论什么副作用. 对于foo(A a),注意方法体中你要玩的是 a=

Java编程:使用Java读取Excel文件内容

微软的ODBC驱动程序把工作表中的第一行作为列名(译者注:即字段名),工作表名作为数据库表名. 要通过JDBC访问工作表,我们还必须创建一个新的ODBC数据源,在Windows 2000系统上创建数据源的过程如下: 进入“控制面板” --> “管理工具” --> “数据源(ODBC)”,(译者注:打开后选择系统DSN),点击添加,在弹出窗口中选择“Driver do Microsoft Excel(*.xls)” 然后在数据源名处输入一个名字myexcel(译者注:相当于数据库名),然后点击“

《编程导论(Java)&#183;1.1.2 颠倒的世界(柏拉图法则)》

<编程导论(Java)>将Plato法则.Liskov原则和Parnas原则作为面向对象编程范式的三大基石. 面向对象范式的第一原则,yqj2065称之为柏拉图法则,它是对象技术的观念范式和心理范式的根源,对象技术是通过颠倒的理念世界而模拟唯物的真实世界. ★柏拉图法则:类的世界独立存在,对象世界由类创建而来. 虽然有人认为,这一原则非常自然,没有必要提出和强调,但是,我发现,对这一原则的理解和接纳程度,决定了你对面向对象的领悟程度. 提出的依据: 1.对象(object)是一个具有浓郁的哲学

《编程导论(Java)&amp;#183;3.2.4 循环语句》

本文全然复制<编程导论(Java)·3.2.4 循环语句>的内容.除[]中的说明文字.请阅读和比較其它编程教材. 我知道.假设我是一个刚開始学习的人,<编程导论(Java)>非常不适合自学.建议同学们阅读时,一定选择一本其它的书同一时候看,或上网. ,由于太一般或简单的内容.或我不想留在书中占用篇幅的东西,都省略了. 毕竟,网络上相关的一般描写叙述的内容.大把大把. 卓别林在<摩登时代>中.说明流水线上的工人在高强度下重复运行同一个动作是多么令人郁闷.然而循环/迭代(l

编程基础知识——Java JNI开发流程(2)

android中使用jni调用本地C++库 android平台上的本地库文件后缀 .so.类似windows上的dll文件. 要在android上使用jni,首先需要下载android ndk. 操作步骤,正常建立android工程,然后在android工程那里右键,属性,选择Android Tools -> Add Native Support.就可以为android工程增加本地库支持. 添加支持后的android工程,会增加jni目录,C++代码就写在这个目录里. 新建一个类,并且使用nat