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

🟡前言

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

活动地址:CSDN21天学习挑战赛

🟡概述

1️⃣原理图

在这里插入图片描述

2️⃣排序原理

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

  2. 将大于或等于分界值的数据放到到数组右边,小于分界值的数据放到数组的左边
    此时左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值

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

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

🟡拆分及分治思想

1️⃣拆分的解题思路

  1. 找一个基准值(一般是数组第一个元素),并用两个“指针”指向数组的头部和尾部
  2. 从右向左(从尾到头) 搜索一个比基准值小的元素,当找到时停止搜索并记录指针位置

在这里插入图片描述

  1. 从左到右(从头到尾)搜索一个比基准值大的元素,当找到时停止搜索并记录指针位置
    在这里插入图片描述

  2. 交换左右指针的位置
    在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述

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

在这里插入图片描述

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;
    }
}

🟡结语

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

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alita11101_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值