不懂就看看--快速排序和荷兰国旗问题

简介: 任取待排序元素序列中的某个元素(例如取第一个元素)作为基准,按照该元素的排序码大小,将整个元素序列划分为左右两个子序列:左侧子序列中的排序码都小于基准元素的排序码,右侧子序列中所有元素的排序码都大于或等于基准元素的排序码。基准元素则排在两个子序列中间(这也是该元素最终应安放的位置)。然后分别对这两个子序列重复实行上述方法(递归过程),直到所有元素都排在相应位置上为止。

快速排序


概念:

任取待排序元素序列中的某个元素(例如取第一个元素)作为基准,按照该元素的排序码大小,将整个元素序列划分为左右两个子序列:左侧子序列中的排序码都小于基准元素的排序码,右侧子序列中所有元素的排序码都大于或等于基准元素的排序码。基准元素则排在两个子序列中间(这也是该元素最终应安放的位置)。然后分别对这两个子序列重复实行上述方法(递归过程),直到所有元素都排在相应位置上为止。

简单来说:基于交换思想对冒泡排序的优化,也称为分区的交换排序。核心是划分,可以用递归来实现。

核心代码:

public class QuickSort {
    public static void quickSort(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        quickSort(arr, 0, arr.length - 1);
    }
    // arr[l...r] 排好序
    public static void quickSort(int[] arr, int L, int R) {
        if (L < R) {
            //随机取一个值
            swap(arr, L + (int) (Math.random() * (R - L + 1)), R);
            int[] p = partition(arr, L, R);
            quickSort(arr, L, p[0] - 1);// p【0】 --》等于区域的左边界  减一则为小于区域的
            quickSort(arr, p[1] + 1, R);// p【1】 --》 等于区域右边界  
        }
    }
    /**
     * 
     * 这是一个处理arr【l...r】的函数
     * 默认以arr【r】 做划分,arr【r】--》p    p《  ==p  》p
     * 返回等于区域(左边界,右边界) 所以返回一个长度为2的数组res,res【0】,res【1】
     * 
     */
    private static int[] partition(int[] arr, int L, int R) {
        int less = L - 1; //< 区右边界
        int more = R;    // >区左边界
        while (L < more) {// L表示当前数的位置,arr[R] -> 划分值
            if (arr[L] < arr[R]) { //当前数 < 划分值
                swap(arr, ++less, L++);
            } else if (arr[L] > arr[R]) {  //当前数 > 划分值
                swap(arr, --more, L);
            } else {
                L++;
            }
        }
        swap(arr, more, R);
        return new int[]{less + 1, more};
    }
    private static void swap(int[] arr, int i, int j) {
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }
}


图例

荷兰国旗问题

网络异常,图片无法展示
|

给定一个数组arr和一个数num,请把小于num的数放在数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边,要求额外空间复杂度O(1),时间复杂度O(N)

有了上面的快速排序的了解,将数组分成三块。在左边设置了一个大于等于区,这个问题可以在左边设置一个小于区,在右边设置一个大于区,不断向中间逼近,最终中间就是相等的数字,然后跟上面快排的思想基本一致,代码如下:

private static int[] partition(int[] arr, int L, int R) {
        int less = L - 1; //< 区右边界
        int more = R;    // >区左边界
        while (L < more) {// L表示当前数的位置,arr[R] -> 划分值
            if (arr[L] < arr[R]) { //当前数 < 划分值
                swap(arr, ++less, L++);
            } else if (arr[L] > arr[R]) {  //当前数 > 划分值
                swap(arr, --more, L);
            } else {
                L++;
            }
        }
        swap(arr, more, R);
        return new int[]{less + 1, more};
    }
//比较排序
    private static void swap(int[] arr, int i, int j) {
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }


总结:类似C语言的双指针的移动,当小于num时,则左指针带着区域移动。

、、、

目录
相关文章
|
数据采集 编解码 JSON
【Python】bug汇总
【Python】bug汇总
791 0
|
消息中间件 Linux 数据安全/隐私保护
linux mq的安装并设置开机启动 图文!!
linux mq的安装并设置开机启动 图文!!
796 0
|
7月前
|
机器学习/深度学习 人工智能 自然语言处理
阶跃星辰开源! Step 3 :最新一代基础大模型 ,多模推理,极致效率
阶跃星辰开源新一代大模型 Step 3,采用 MoE 架构,参数量达 321B,激活参数 32B,平衡推理效率与资源利用,具备强大多模态能力,支持复杂推理与视觉分析,已在多个评测集取得领先成绩。
1039 10
|
数据采集 JSON 测试技术
如何在Python中高效实现CSV到JSON的数据转换
在实际项目中,数据格式转换是常见问题,尤其从CSV到JSON的转换。本文深入探讨了多种转换方法,涵盖Python基础实现、数据预处理、错误处理、性能优化及调试验证技巧。通过分块处理、并行处理等手段提升大文件转换效率,并介绍如何封装为命令行工具或Web API,实现自动化批量处理。关键点包括基础实现、数据清洗、异常捕获、性能优化和单元测试,确保转换流程稳定高效。
630 83
|
前端开发 JavaScript 关系型数据库
2025 年前端与后端开发方向的抉择与展望-优雅草卓伊凡
2025 年前端与后端开发方向的抉择与展望-优雅草卓伊凡
870 5
2025 年前端与后端开发方向的抉择与展望-优雅草卓伊凡
|
11月前
|
人工智能 Go
[go]Slice 切片原理
本文详细介绍了Go语言中的切片(slice)数据结构,包括其定义、创建方式、扩容机制及常见操作。切片是一种动态数组,依托底层数组实现,具有灵活的扩容和传递特性。文章解析了切片的内部结构(包含指向底层数组的指针、长度和容量),并探讨了通过`make`创建切片、基于数组生成切片以及切片扩容的规则。此外,还分析了`append`函数的工作原理及其可能引发的扩容问题,以及切片拷贝时需要注意的细节。最后,通过典型面试题深入讲解了切片在函数间传递时的行为特点,帮助读者更好地理解和使用Go语言中的切片。
361 0
|
存储 缓存 应用服务中间件
|
城市大脑 安全 计算机视觉
课时13:城市数据大脑介绍
阿里云与杭州市合作打造的城市数据大脑,通过智能调控红绿灯、实时视频分析交通事件,提升了道路通行效率。如今,城市大脑不仅能主动发现并处理交通事故,还能为救护车规划最优路线,从被动接警转变为积极应对,使城市交通更加顺畅和安全。交警们希望通过这一系统,让杭州变得更加美好,实现更愉快的出行体验。
678 0
|
存储 算法 C语言
【C语言】深入浅出:C语言链表的全面解析
链表是一种重要的基础数据结构,适用于频繁的插入和删除操作。通过本篇详细讲解了单链表、双向链表和循环链表的概念和实现,以及各类常用操作的示例代码。掌握链表的使用对于理解更复杂的数据结构和算法具有重要意义。
3968 6
|
SQL 关系型数据库 MySQL
Go语言项目高效对接SQL数据库:实践技巧与方法
在Go语言项目中,与SQL数据库进行对接是一项基础且重要的任务
356 11

热门文章

最新文章

下一篇
开通oss服务