快速排序思想

作者: 小石读史 | 来源:发表于2019-11-25 20:50 被阅读0次

快速排序尤其适用于对大数据的排序,它的高速和高效无愧于“快速”两个字。

1、快速排序的基本思想:

快速排序所采用的思想是分治的思想。所谓分治,就是指以一个数为基准,将序列中的其他数往它两边“扔”。以从小到大排序为例,比它小的都“扔”到它的左边,比它大的都“扔”到它的右边,然后左右两边再分别重复这个操作,不停地分,直至分到每一个分区的基准数的左边或者右边都只剩一个数为止。这时排序也就完成了。

2、快速排序的三个步骤:

(1)选择基准:在待排序列中,按照某种方式挑出一个元素,作为 "基准"(pivot)

(2)分割操作:以该基准在序列中的实际位置,把序列分成两个子序列。此时,在基准左边的元素都比该基准小,在基准右边的元素都比基准大

(3)递归地对两个序列进行快速排序,直到序列为空或者只有一个元素。

案例图:

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

1574685745(1).jpg

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

image.png

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

6 1 2 5 9 3 4 7 10 8

image.png

到此,第一次交换结束。接下来开始哨兵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.png

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

案例图:

image.png

快速排序的性能高度依赖于你选择的基准值

代码实现:


package com.ac;

/**

* 小鹅通接口测试

*/

public class Test {

public static void main(String[] a){

int [] b = {1,6,8,7,3,5,16,4,8,36,13,44};

quickSort(b);

for (int i:b) {

System.out.print(i +" ");

}

}

/**

    * 快速排序

    * @param array

    */

    public static void quickSort(int[] array) {

int len;

if(array ==null

                || (len = array.length) ==0

                || len ==1) {

return ;

}

sort(array,0, len -1);

}

/**

    * 快排核心算法,递归实现

    * @param array

    * @param left

    * @param right

    */

    public static void sort(int[] array,int left,int right) {

if(left > right) {

return;

}

// base中存放基准数

        int base = array[left];

int i = left, j = right;

while(i != j) {

// 顺序很重要,先从右边开始往左找,直到找到比base值小的数

            while(array[j] >= base && i < j) {

j--;

}

// 再从左往右边找,直到找到比base值大的数

            while(array[i] <= base && i < j) {

i++;

}

// 上面的循环结束表示找到了位置或者(i>=j)了,交换两个数在数组中的位置

            if(i < j) {

int tmp = array[i];

array[i] = array[j];

array[j] = tmp;

}

}

// 将基准数放到中间的位置(基准数归位)

        array[left] = array[i];

array[i] = base;

// 递归,继续向基准的左右两边执行和上面同样的操作

        // i的索引处为上面已确定好的基准值的位置,无需再处理

        sort(array, left, i -1);

sort(array, i +1, right);

}

}

部分内容参考文章:https://blog.csdn.net/shujuelin/article/details/82423852

相关文章

  • 快速排序

    快速排序 思想 快速排序采用的思想是分治思想。快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot)...

  • 快速排序

    快速排序思想 快速排序采用的思想是分治思想。 快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot)...

  • 数据结构与算法之美-快速排序

    QuickSort - 快速排序 核心:快速排序是采用分治思想的典型应用。 基本思想: 从要排序数组中下标从 p ...

  • 懵X排序算法:快速排序

    原文地址:https://xeblog.cn/articles/17 快速排序基本思想 快速排序使用的是 分治思想...

  • 快速排序

    快速排序应用广泛。长度为N的数组和运行时间成正比NlogN 快速排序思想 快速排序是一种分治排序的思想。它讲一个数...

  • 算法基础课1 快速排序 归并排序 整数二分 浮点数二分

    1:快速排序 先上模板 然后是习题 785. 快速排序 快速排序的基本思想是基于分治大致思想是假设我们有一个集合q...

  • 快速排序

    概念 快速排序(Quicksort)是对冒泡排序的一种改进。 原理 快速排序采用的思想是分治思想。 选择一个基准元...

  • 快速排序算法

    快速排序思想 看网上讲快速排序半天才搞懂,总结一下,快速排序核心思想是保证每个元素其所有左边元素比其小,所有右边元...

  • 数据结构与算法-冒泡排序&快速排序

    冒泡排序 排序思想:通过一趟排序将最小的数升至最上层。 思想2:将大数沉底: 快速排序 排序思想:通过一趟排序将顺...

  • 算法(四)--快速排序

    快速排序基本思想 快速排序(Quicksort)是对冒泡排序的一种改进。快速排序由C. A. R. Hoare在1...

网友评论

    本文标题:快速排序思想

    本文链接:https://www.haomeiwen.com/subject/txxswctx.html