基本实现思路:

从数列中挑出一个元素,称为 "基准"

重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分割之后,该基准是它的最后位置。这个称为分割操作。

递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。

假设我们现在对“6 1 2 7 9 3 4 5 10 8”这个10个数进行排序。首先在这个序列中随便找一个数作为基准数(不要被这个名词吓到了,就是一个用来参照的数,待会你就知道它用来做啥的了)。为了方便,就让第一个数6作为基准数吧。接下来,需要将这个序列中所有比基准数大的数放在6的右边,比基准数小的数放在6的左边,类似下面这种排列。

3 1 2 5 4 6 9 7 10 8

分别从初始序列“6 1 2 7 9 3 4 5 10 8”两端开始“探测”。先从右往左找一个小于6的数,再从左往右找一个大于6的数,然后交换他们。这里可以用两个变量i和j,分别指向序列最左边和最右边。我们为这两个变量起个好听的名字“哨兵i”和“哨兵j”。刚开始的时候让哨兵i指向序列的最左边(即i=1),指向数字6。让哨兵j指向序列的最右边(即j=10),指向数字8。

image

首先哨兵j开始出动。因为此处设置的基准数是最左边的数,所以需要让哨兵j先出动,这一点非常重要(请自己想一想为什么)。哨兵j一步一步地向左挪动(即j--),直到找到一个小于6的数停下来。接下来哨兵i再一步一步向右挪动(即i++),直到找到一个数大于6的数停下来。最后哨兵j停在了数字5面前,哨兵i停在了数字7面前。

image

image

现在交换哨兵i和哨兵j所指向的元素的值。交换之后的序列如下。

6 1 2 5 9 3 4 7 10 8

image

image

到此,第一次交换结束。接下来开始哨兵j继续向左挪动(再友情提醒,每次必须是哨兵j先出发)。他发现了4(比基准数6要小,满足要求)之后停了下来。哨兵i也继续向右挪动的,他发现了9(比基准数6要大,满足要求)之后停了下来。此时再次进行交换,交换之后的序列如下。

6 1 2 5 4 3 9 7 10 8

第二次交换结束,“探测”继续。哨兵j继续向左挪动,他发现了3(比基准数6要小,满足要求)之后又停了下来。哨兵i继续向右移动,糟啦!此时哨兵i和哨兵j相遇了,哨兵i和哨兵j都走到3面前。说明此时“探测”结束。我们将基准数6和3进行交换。交换之后的序列如下。

3 1 2 5 4 6 9 7 10 8

image

image

image

到此第一轮“探测”真正结束。此时以基准数6为分界点,6左边的数都小于等于6,6右边的数都大于等于6。回顾一下刚才的过程,其实哨兵j的使命就是要找小于基准数的数,而哨兵i的使命就是要找大于基准数的数,直到i和j碰头为止。

OK,解释完毕。现在基准数6已经归位,它正好处在序列的第6位。此时我们已经将原来的序列,以6为分界点拆分成了两个序列,左边的序列是“3 1 2 5 4”,右边的序列是“9 7 10 8”。接下来还需要分别处理这两个序列。因为6左边和右边的序列目前都还是很混乱的。不过不要紧,我们已经掌握了方法,接下来只要模拟刚才的方法分别处理6左边和右边的序列即可。现在先来处理6左边的序列现吧。

左边的序列是“3 1 2 5 4”。请将这个序列以3为基准数进行调整,使得3左边的数都小于等于3,3右边的数都大于等于3。好了开始动笔吧。

如果你模拟的没有错,调整完毕之后的序列的顺序应该是。

2 1 3 5 4

OK,现在3已经归位。接下来需要处理3左边的序列“2 1”和右边的序列“5 4”。对序列“2 1”以2为基准数进行调整,处理完毕之后的序列为“1 2”,到此2已经归位。序列“1”只有一个数,也不需要进行任何处理。至此我们对序列“2 1”已全部处理完毕,得到序列是“1 2”。序列“5 4”的处理也仿照此方法,最后得到的序列如下。

1 2 3 4 5 6 9 7 10 8

对于序列“9 7 10 8”也模拟刚才的过程,直到不可拆分出新的子序列为止。最终将会得到这样的序列,如下。

1 2 3 4 5 6 7 8 9 10

到此,排序完全结束。细心的同学可能已经发现,快速排序的每一轮处理其实就是将这一轮的基准数归位,直到所有的数都归位为止,排序就结束了。下面上个霸气的图来描述下整个算法的处理过程。

image

快速排序之所比较快,因为相比冒泡排序,每次交换是跳跃式的。每次排序的时候设置一个基准点,将小于等于基准点的数全部放到基准点的左边,将大于等于基准点的数全部放到基准点的右边。这样在每次交换的时候就不会像冒泡排序一样每次只能在相邻的数之间进行交换,交换的距离就大的多了。因此总的比较和交换次数就少了,速度自然就提高了。当然在最坏的情况下,仍可能是相邻的两个数进行了交换。因此快速排序的最差时间复杂度和冒泡排序是一样的都是O(N2),它的平均时间复杂度为O(NlogN)。其实快速排序是基于一种叫做“二分”的思想。

代码

public class QuickSort {

public static void quickSort(int[] arr, int low, int high) {

int left, right, base, temp;

if (low > high) {

return;

}

left = low;

right = high;

//temp就是基准位

base = arr[low];

while (left < right) {

//先看右边,依次往左递减

while (base <= arr[right] && left < right) {

right--;

}

//再看左边,依次往右递增

while (base >= arr[left] && left < right) {

left++;

}

//如果满足条件则交换

if (left < right) {

temp = arr[right];

arr[right] = arr[left];

arr[left] = temp;

}

}

//最后将基准为与i和j相等位置的数字交换

arr[low] = arr[left];

arr[left] = base;

//递归调用左半数组

quickSort(arr, low, right - 1);

//递归调用右半数组

quickSort(arr, right + 1, high);

}

public static void main(String[] args) {

int[] arr = {10, 7, 2, 4, 7, 62, 3, 4, 2, 1, 8, 9, 19};

quickSort(arr, 0, arr.length - 1);

for (int i = 0; i < arr.length; i++) {

System.out.println(arr[i]);

}

}

}

java快拍_Java排序之快排相关推荐

  1. java 比较算法_JAVA排序算法实现和比较:冒泡,桶,选择,快排,归并

    一.冒泡排序: 实现思想: 重复地走访过要排序的元素列,一次比较两个相邻的元素,如果他们的顺序(如从大到小.首字母从A到Z)错误就把他们交换过来.走访元素的工作是重复地进行直到没有相邻元素需要交换,也 ...

  2. java开发学不会_JAVA学不会,快期末了,怎么办?

    学习一门计算机语言老师只是入门及辅助,主要还是靠自己.如果一直跟着老师的结果可以入坑.我上大学时,好多同学入坑.而主要的学习方式是实操.上手写代码,而代码也不是光照书抄,那没意思.一般是要求在例题的基 ...

  3. java sort方法_Java排序方法sort用法详解

    本文实例为大家分享了java对数组.集合的排序方法,供大家参考,具体内容如下 对数组的排序: //对数组排序 public void arraySort(){ int[] arr = {1,4,6,3 ...

  4. java堆排序工具包_JAVA 排序工具类

    提供了以下排序:冒泡排序 选择排序 插入排序 希尔排序 快速排序 归并排序 桶排序 堆排序 package com.xingej.algorithm.sort;import java.util.Arr ...

  5. java sort 插入排序_Java排序之InsertionSort插入排序的实例

    插入排序 の implementation 插入排序就像打赌的时候,比如双扣.抽牌的时候,一次拿一张牌,这张牌和之前的牌一张张比较.选择把这张牌插入什么位置,排好顺序的位置后打牌更顺.要不然得一个一个 ...

  6. java排列序数_JAVA排序数字字母混合

    展开全部 import java.util.ArrayList; import java.util.List; public class Sort { /** * @param args */ pub ...

  7. 【java】java 分支预测 Java处理排序后的数组比没有排序的快

    1.概述 今天周日,没什么重要的事情要做,于是我早早的就醒来了.看了一会渡边淳一的书,内心逐渐感到平静--心情不佳的时候,书好像是最好的药物.心情平静了,就需要做一些更有意义的事情--逛技术网站,学习 ...

  8. 排序算法--快排的优化

    排序算法–快排的优化 下面是我写的一种快排: #include <iostream> #include <stdlib.h>using namespace std;void P ...

  9. 为什么?为什么?Java处理排序后的数组比没有排序的快?想过没有?

    先看再点赞,给自己一点思考的时间,微信搜索[沉默王二]关注这个有颜值却假装靠才华苟且的程序员. 本文 GitHub github.com/itwanger 已收录,里面还有我精心为你准备的一线大厂面试 ...

最新文章

  1. 20以内混合加减法100题_一年级数学20以内加减法混合运算练习题,寒假练习巩固!...
  2. VTK修炼之道28:图像统计_灰度直方图计算
  3. JavaScript基础07-day09【嵌套for循环、break和continue、对象、数据类型、对象字面量、函数】
  4. 一文彻底搞懂Cookie、Session、Token到底是什么
  5. Vue 自定义指令上报 Google Analytics 事件统计
  6. 搭建了Pycharm对话平台
  7. Android本地应用程序应用方式介绍
  8. scrapy爬取某网站,模拟登陆过程中遇到的那些坑
  9. 移动通信发展史及原理学习
  10. 基础篇——树莓派通用引脚定义
  11. 【linux】redhat笔记:红帽企业Linux入门与安装
  12. js 根据公历日期 算出农历_显示阴历(农历)日期的js代码
  13. category 详解
  14. STM32F4 ETR计数
  15. go mgo包 简单封装 mongodb 数据库驱动
  16. 【二叉树:3】线索二叉树
  17. 360安全卫士大战“病毒之王”——最新磁碟机变种
  18. wireshark编译基于openflow1.3协议开发
  19. 数值分析实验 实验3-1 牛顿下山法 python3实现
  20. chrome书签变透明看不清怎么办

热门文章

  1. obs---关于Windows 系统下 OBS 黑屏问题的处理方法
  2. 将mp3音频剪切器收藏起来使用
  3. Fiddler手机抓包指南
  4. 计算机操作系统 精选模拟试题及答案
  5. linux文件权限 421,Linux的文件权限设置为什么可以使用421
  6. Qualcomm 蓝牙耳机FAQ(2 )--SINK工程支持百分之一精度的电池电量显示功能实现
  7. Jenkins 2.X free-style CI/CD流水线搭建(一)
  8. python selenium爬虫保存_爬虫之自动保存文档-使用python/selenium
  9. 大型WAV文件的播放
  10. 求超大文件上传方案( js )