原理介绍

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

具体实现

左右指针法

  • 实现说明

  • 代码实现

      public static void sort1(int[] arr, int start, int end) {
    if (start >= end) {
    return;
    }
    int key = end;
    int left = start;
    int right = end - 1;
    int temp;
    //当left和right相遇时结束
    while (left < right) {
    //移动left至第一个大于基准的元素
    while (left < right && arr[left] <= arr[key]) {
    left++;
    }
    //移动right至第一个小于基准的元素
    while (left < right && arr[right] >= arr[key]) {
    right--;
    }
    //交换left和right元素
    temp = arr[left];
    arr[left] = arr[right];
    arr[right] = temp;
    }
    //交换相遇位置和基准
    if (arr[left] > arr[key]) {
    temp = arr[left];
    arr[left] = arr[key];
    arr[key] = temp;
    }
    //递归
    sort1(arr, start, left - 1);
    sort1(arr, right + 1, end);
    }
  • 细节说明

    1. 下面的代码为什么还要判断left < right?

       while (left < right && arr[left] <= arr[key])

      key是序列的最后一个,right是key前一个位置,如果arr[right]=arr[key],满足arr[left]<=arr[key],然后left++,这时候left就会移动到key的位置

    2. 出了while循环并不是直接进行交换

       if (arr[left] > arr[key]) {
      temp = arr[left];
      arr[left] = arr[key];
      arr[key] = temp;
      }

      当left和right重合时,由于不满足left<right退出while循环不会继续右移left,若此时left元素依然小于基准元素则无需进行交换。

挖坑法

  • 实现说明

  • 代码实现

      public static void sort2(int[] arr, int start, int end) {
    if (start >= end) {
    return;
    }
    int mark = arr[end];
    int left = start;
    int right = end;
    int key = end;
    //当left和right重合时结束
    while (left < right) {
    //left右移至第一个大于基准的位置
    while (left < right && arr[left] <= mark) {
    left++;
    }
    //将left元素填入坑中,令left位置为新坑
    arr[key] = arr[left];
    key = left;
    //right左移至第一个小于基准的位置
    while (left < right && arr[right] >= mark) {
    right--;
    }
    //将right元素填入坑中,令right位置为新坑
    arr[key] = arr[right];
    key = right;
    }
    //将基准元素放入重合位置
    arr[left] = mark;
    sort2(arr, start, left - 1);
    sort2(arr, right + 1, end);
    }

    由于坑位和right都为end,进行简化

      public static void sort3(int[] arr, int start, int end) {
    if (start >= end) {
    return;
    }
    int mark = arr[end];
    int left = start;
    int right = end;
    //当left和right重合时结束
    while (left < right) {
    //left右移至第一个大于基准的位置
    while (left < right && arr[left] <= mark) {
    left++;
    }
    //将left元素填入坑中,令left位置为新坑
    arr[right] = arr[left];
    //right左移至第一个小于基准的位置
    while (left < right && arr[right] >= mark) {
    right--;
    }
    //将right元素填入坑中,令right位置为新坑
    arr[left] = arr[right];
    }
    //将基准元素放入重合位置
    arr[left] = mark;
    sort2(arr, start, left - 1);
    sort2(arr, right + 1, end);
    }

前后指针法

  • 实现说明

  • 代码实现

      public static void sort4(int[] arr, int start, int end){
    if (start >= end) {
    return;
    }
    int key = end;
    int cur = start;
    int pre = cur - 1;
    int temp;
    //结束循环时cur在基准处
    while (cur < key) {
    //当cur元素小于基准元素时才会pre++
    if (arr[cur] < arr[key] && ++pre != cur) {
    temp = arr[cur];
    arr[cur] = arr[pre];
    arr[pre] = temp;
    }
    cur++;
    }
    temp = arr[cur];
    arr[cur] = arr[++pre];
    arr[pre] = temp;
    sort4(arr, start, pre - 1);
    sort4(arr, pre + 1, end);
    }

优化方案

三数取中

选用待排数组最左边、最右边和最中间的三个元素的中间值作为基准

随机选取基准

在待排序列是部分有序时,固定选取枢轴使快排效率底下,要缓解这种情况,就引入了随机选取枢轴

根据分区大小调整算法

当分区的规模达到一定小时,停止快速排序算法,使用选择排序等算法

相同元素相聚

在一次分割结束后,可以把与Key相等的元素聚在一起,继续下次分割时,不用再对与key相等元素分割

  1. 在划分过程中,把与key相等元素放入数组的两端

  2. 划分结束后,把与key相等的元素移到基准周围

快速排序(Quick Sort)及优化的更多相关文章

  1. [算法] 快速排序 Quick Sort

    快速排序(Quick Sort)使用分治法策略. 它的基本思想是:选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分:其中一部分的所有数据都比另外一部分的所有数据都要小.然后,再按此方法对这 ...

  2. 基础排序算法之快速排序(Quick Sort)

    快速排序(Quick Sort)同样是使用了分治法的思想,相比于其他的排序方法,它所用到的空间更少,因为其可以实现原地排序.同时如果随机选取中心枢(pivot),它也是一个随机算法.最重要的是,快速排 ...

  3. 快速排序Quick sort

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

  4. Java中的经典算法之快速排序(Quick Sort)

    Java中的经典算法之快速排序(Quick Sort) 快速排序的思想 基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小, 然后再按此方法对 ...

  5. 排序算法 - 快速排序(Quick Sort)

    算法思想 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序.它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod). (1) 分治法的基本思想  ...

  6. quicksort 快速排序 quick sort

    * Java基本版 package cn.mediamix; import java.util.LinkedList; public class QuickSort { public static v ...

  7. 基础算法之快速排序Quick Sort

    原理 快速排序(Quicksort)是对冒泡排序的一种改进. 从数列中挑出一个元素,称为"基准"(pivot); 排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的 ...

  8. 快速排序算法回顾 --冒泡排序Bubble Sort和快速排序Quick Sort(Python实现)

    冒泡排序的过程是首先将第一个记录的关键字和第二个记录的关键字进行比较,若为逆序,则将两个记录交换,然后比较第二个记录和第三个记录的关键字.以此类推,直至第n-1个记录和第n个记录的关键字进行过比较为止 ...

  9. 快速排序——Quick Sort

    基本思想:(分治) 先从数列中取出一个数作为key值: 将比这个数小的数全部放在它的左边,大于或等于它的数全部放在它的右边: 对左右两个小数列重复第二步,直至各区间只有1个数. 辅助理解:挖坑填数 初 ...

  10. 排序:快速排序Quick Sort

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

随机推荐

  1. make 出错: /usr/bin/ld: cannot find -lrt

    make 出错:/usr/bin/ld: cannot find -lrtcollect2: ld returned 1 exit statusmake: *** [page_parser] Erro ...

  2. 删除临时文件的bat文件

    @echo offecho 正在清除系统垃圾文件,请稍等......del /f /s /q %systemdrive%\*.tmpdel /f /s /q %systemdrive%\*._mpde ...

  3. js处理的8种跨域方法

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  4. java中利用JOptionPane类弹出消息框的部分例子

    转: http://www.cnblogs.com/wangxiuheng/p/4449917.html http://blog.csdn.net/penjie0418/article/details ...

  5. C#箴言之用属性来访问类的私有成员

    在程序中,难免要访问某个对象的私有成员.那么以前实现这类功能的方法有两种,第一种方法最简单,就是把成员访问符从“private”改为“public”即可:而另一个就是提供公有的成员访问函数来进行访问. ...

  6. java基础面试题:如何把一段逗号分割的字符串转换成一个数组? String s = "a" +"b" + "c" + "d";生成几个对象?

    package com.swift; public class Douhao_String_Test { public static void main(String[] args) { /* * 如 ...

  7. 微信小程序页面跳转绑定点击事件

    https://www.cnblogs.com/mrszhou/p/7931747.html

  8. 项目实战2.3-Nginx的“远方表哥”—Tengine

    本文收录在Linux运维企业架构实战系列 今天想起当初研究nginx反向代理负载均衡时,nginx自身的upstream后端配置用着非常不舒服: 当时使用的淘宝基于nginx二次开发的Tengine, ...

  9. 入门学习Linux常用必会命令实例详解

    Linux提供了大量的命令,利用它可以有效地完成大量的工作,如磁盘操作.文件存取.目录操作.进程管理.文件权限设定等.所以,在Linux系统上工作离不开使用系统提供的命令.要想真正理解Linux系统, ...

  10. EventUtil处理js兼容性问题

    var EventUtil={ addHandler:function(element,type,handler){ //添加事件 if(element.addEventListener){ elem ...