算法排序6——快速排序(分治思想)

简介: 对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理

🟡前言


21天挑战赛第二周。本文主要讲述有关快速排序的内容


活动地址CSDN21天学习挑战赛


🟡概述


1️⃣原理图


e47f640c764d4ca1a31fd78d2a4f863f.png


2️⃣排序原理


1.首先设定一个分界值 ,通过该分界值将数组分成左右两部分


2.将大于或等于分界值的数据放到到数组右边,小于分界值的数据放到数组的左边

此时左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值


3.左边和右边的数据可以独立排序;

对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以做类似处理


4.重复上述过程,当左侧和右侧两个部分的数据排完序后,整个数组的排序也就完成了


🟡拆分及分治思想


1️⃣拆分的解题思路


1.找一个基准值(一般是数组第一个元素),并用两个“指针”指向数组的头部和尾部

2.从右向左(从尾到头) 搜索一个比基准值小的元素,当找到时停止搜索并记录指针位置


adef11f56bae4971b0a3410ddb45def4.jpg


3.再从左到右(从头到尾)搜索一个比基准值大的元素,当找到时停止搜索并记录指针位置


1dff2e57cd3a44ceb748eda8a3f54862.jpg


4.交换左右指针的位置


7b5068626fbf4a61933018775a6cdba0.jpg


5.重复上述步骤,直至左右指针指向同一个元素


fa0fc80898a1407382c1712e93477ee5.png


f66bfd95fa2d4dabaad0ca72d26784f7.png


2️⃣拆分中分治思想体现


78408efc528d481383ba2729c04b602b.png


3️⃣拆分的代码实现


    public static int partition(Comparable[]a, int lo, int hi){
        //确定分界值
        Comparable key = a[0];
        //定义两个指针
        int left = lo;
        int right = hi + 1;
        //拆分数组
        while (true){
            //从右往左移动指针,当遇到元素值比key小就停止
            while (less(key, a[--right])){
                if(right == lo){
                    break;
                }
            }
            //从左往右移动指针,当遇到元素值比key大就停止
            while (less(a[++left], key)){
                if (left == hi) {
                    break;
                }
            }
      //当指针指向同一元素时结束循环
            if(left >= right){
                break;
            }
            //当左边的元素值更大时,交换两者位置
            else {
                exch(a,left,right);
            }
        }
        //当完成拆分后,交换当前分界值的指针与首个元素对应的指针
        exch(a, lo, right);
        return right;
    }


🟡调用API实现快速排序


1️⃣构造方法成员方法


构造方法


Quick();


成员方法


  • public static void sort(Comparable[]a):对数组a中元素进行排序
  • public static boolean less(Comparable x, Comparable y):判断x是否小于y
  • public static void exch(Comparable[]a, int i, int j):交换数组a中下标为 i 和 j 的元素
  • public static int partition(Comparable[]a, int lo, int hi):对数组a中索引从lo到hi之间元素分组,返回分组界限对应索引
  • public static void sort(Comparable[]a, int lo, int hi):对数组a中从索引lo到索引hi之间元素进行排序


2️⃣解题思路


1.定义less方法用来比较元素大小

2.定义exch方法用来交换数组内元素

3.定义一个sort方法来对数组内元素排序

4.定义一个partition方法来对数组进行拆分排序

5.定义一个sort的重载方法,并在方法内调用sort方法对子组排序(递归)


3️⃣完整代码


public class QuickSort {
    private static void exch(Comparable[] a, int i, int j){
        Comparable temp;
        temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
    public static boolean less(Comparable x, Comparable y){
        return x.compareTo(y) < 0;
    }
    public static void sort(Comparable[] a){
        int lo = 0;
        int hi = a.length-1;
        sort(a,lo,hi);
    }
    public static void sort(Comparable[]a, int lo, int hi){
        //安全性校验
        if(hi <= lo){
            return;
        }
        //调用方法对数组进行分组
        int partition = partition(a, lo, hi);
        //对左子数组排序
        sort(a,lo,partition-1);
        //对右子数组排序
        sort(a,partition+1,hi);
    }
    public static int partition(Comparable[]a, int lo, int hi){
        //确定分界值
        Comparable key = a[0];
        //定义两个指针
        int left = lo;
        int right = hi + 1;
        //拆分数组
        while (true){
            //从右往左移动指针,当遇到元素值比key小就停止
            while (less(key, a[--right])){
                if(right == lo){
                    break;
                }
            }
            //从左往右移动指针,当遇到元素值比key大就停止
            while (less(a[++left], key)){
                if (left == hi) {
                    break;
                }
            }
            if(left >= right){
                break;
            }
            //当左边的元素值更大时,交换两者位置
            else {
                exch(a,left,right);
            }
        }
        //当完成拆分后,交换分界值
        exch(a, lo, right);
        return right;
    }
}


🟡结语


快速排序利用了递归和分治思想来实现,至此所有的排序都已经讲解完毕,接下来是有关链表的知识

相关文章
|
3月前
|
算法
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
|
15天前
|
算法 搜索推荐 Shell
数据结构与算法学习十二:希尔排序、快速排序(递归、好理解)、归并排序(递归、难理解)
这篇文章介绍了希尔排序、快速排序和归并排序三种排序算法的基本概念、实现思路、代码实现及其测试结果。
13 1
|
22天前
|
搜索推荐 Shell
解析排序算法:十大排序方法的工作原理与性能比较
解析排序算法:十大排序方法的工作原理与性能比较
37 9
|
15天前
|
算法 搜索推荐 Java
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
基数排序是一种稳定的排序算法,通过将数字按位数切割并分配到不同的桶中,以空间换时间的方式实现快速排序,但占用内存较大,不适合含有负数的数组。
17 0
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
|
22天前
|
搜索推荐 Java Go
深入了解快速排序算法
深入了解快速排序算法
22 2
|
14天前
|
算法
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
❤️算法笔记❤️-(每日一刷-83、删除排序链表中的重复项)
27 0
|
19天前
|
存储 搜索推荐 算法
【排序算法(二)】——冒泡排序、快速排序和归并排序—>深层解析
【排序算法(二)】——冒泡排序、快速排序和归并排序—>深层解析
|
21天前
|
存储 算法 搜索推荐
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
算法进阶之路:Python 归并排序深度剖析,让数据排序变得艺术起来!
54 0
|
21天前
|
算法 Python
Python算法编程:冒泡排序、选择排序、快速排序
Python算法编程:冒泡排序、选择排序、快速排序
17 0
|
23天前
|
搜索推荐 C语言 C++
【C语言】指针篇-精通库中的快速排序算法:巧妙掌握技巧(4/5)
【C语言】指针篇-精通库中的快速排序算法:巧妙掌握技巧(4/5)