Java算法OJ(7)随机快速排序

fb7f538c48644005a107eb6a3a760d38.jpeg


目录

1.前言

2.正文

1. 快速排序的基本原理

2. 随机快速排序的改进

3. 随机快速排序的步骤

3.小结


1.前言

哈喽大家好吖,今儿给大家带来算法—随机快速排序相关知识点,废话不多说让我们开始。

2.正文

在了解随机快排之前,先了解一下原始的快速排序是什么:

1. 快速排序的基本原理

快速排序是一种基于分治法的排序算法,主要步骤包括:

  1. 选取基准:从数组中选取一个基准元素,通常选择第一个元素、最后一个元素或中间元素。
  2. 分区:将数组分为两个子数组,使得左子数组的元素都小于基准,右子数组的元素都大于基准。
  3. 递归排序:分别对左、右子数组递归进行快速排序,直到子数组的长度为1。
public static void quickSort1(int[] arr, int l, int r) {if (l >= r) {return;}int x = arr[l + (int) (Math.random() * (r - l + 1))]; // 随机选择基准值int mid = partition1(arr, l, r, x); // 分区操作quickSort1(arr, l, mid - 1); // 递归排序左部分quickSort1(arr, mid + 1, r); // 递归排序右部分
}

 分区过程(partition1

  • 遍历 arr[l...r] 的所有元素,将小于等于 x 的元素放到左侧(<=x 区域),大于 x 的元素放到右侧。
  • 使用一个变量 a 来记录 <=x 区域的边界,并动态更新位置。
  • 遍历完成后,将等于 x 的最后一个元素放在 <=x 区域的最后位置,以确保分区后的基准值处于正确位置。
public static int partition1(int[] arr, int l, int r, int x) {int a = l, xi = 0; // a 记录 <=x 区域的边界,xi 用于记录 x 的位置for (int i = l; i <= r; i++) {if (arr[i] <= x) {swap(arr, a, i);if (arr[a] == x) {xi = a;}a++;}}swap(arr, xi, a - 1); // 将 x 放到 <=x 区域的末尾return a - 1; // 返回 x 的最终位置
}

2. 随机快速排序的改进

在传统的快速排序中,选择固定的基准可能导致较差的时间复杂度。比如,如果数组已经有序或逆序,选择第一个或最后一个元素作为基准会导致算法的性能退化到 O(n2)O(n^2)O(n2)。

改进版使用了“荷兰国旗问题”的分区方式,将数组分为小于基准值、等于基准值、大于基准值三部分,分别放在左中右,即不再是使用俩块的分区方式,而是在一个分区中将所有都等于基准值的数字都放到中间。这样在处理大量重复元素时效率更高。

3. 随机快速排序的步骤

public static void quickSort2(int[] arr, int l, int r) {if (l >= r) {return;}int x = arr[l + (int) (Math.random() * (r - l + 1))]; // 随机选择基准值partition2(arr, l, r, x); // 分区操作int left = first; // 左边界(小于 x 的部分的末尾)int right = last; // 右边界(等于 x 的部分的末尾)quickSort2(arr, l, left - 1); // 递归排序小于 x 的部分quickSort2(arr, right + 1, r); // 递归排序大于 x 的部分
}

分区过程(partition2

  • partition2 使用双指针方法实现了“荷兰国旗”分区。
  • 使用三个区域:<x(小于 x 的区域)、==x(等于 x 的区域)和 >x(大于 x 的区域)。
  • 通过遍历 arr[l...r],将小于 x 的元素放在左边,大于 x 的元素放在右边,等于 x 的元素放在中间。
  • 更新全局变量 firstlast,分别指向 ==x 区域的左右边界
public static int first, last;public static void partition2(int[] arr, int l, int r, int x) {first = l;last = r;int i = l;while (i <= last) {if (arr[i] == x) {i++;} else if (arr[i] < x) {swap(arr, first++, i++);} else {swap(arr, i, last--);}}
}

逻辑

  • 初始时 first 指向 llast 指向 ri 指针用于遍历数组。
  • arr[i] == x 时,i 向右移动,继续检查下一个元素。
  • arr[i] < x 时,表示当前元素属于 <x 区域,将其交换到 first 所指位置,并同时增大 firsti
  • arr[i] > x 时,表示当前元素属于 >x 区域,将其交换到 last 所指位置,并减少 last
  • 这样在遍历完成后,<x 区域、==x 区域和 >x 区域的边界已经划分完毕,firstlast 分别指向 ==x 区域的左边界和右边界。
public static void swap(int[] nums, int i, int j) {int tmp = nums[i];nums[i] = nums[j];nums[j] = tmp;}

这里再对比一下改进前和改进后的不同:

| 比较项       | quickSort1                                    | quickSort2                                                |
|--------------|----------------------------------------------|-----------------------------------------------------------|
| **效率**     | 适合普通数据集,但处理重复元素效率较低             | “荷兰国旗”分区方式更适合含有重复元素的数组,将等于基准值的部分集中在中间,减少重复元素的处理次数 |
| **递归调用** | 递归划分基于一个位置                             | 递归划分基于两个位置(`first` 和 `last`),有效减少递归深度 |
| **使用场景** | 适合一般数据集,重复元素较多时效率较低             | 推荐用于重复元素较多的数组,一般情况下也更高效                  |

下面这俩个是俩个排序的测试链接,一个是填函数风格,另一个是acm练习风格,本文仅将核心部分罗列出来,剩下的调试部分就交给大家了。

P1177 【模板】排序 - 洛谷 | 计算机科学教育新生态https://www.luogu.com.cn/problem/P1177912. 排序数组 - 力扣(LeetCode)https://leetcode.cn/problems/sort-an-array/description/

3.小结

今天的分享到这里就结束了,喜欢的小伙伴点点赞点点关注,你的支持就是对我最大的鼓励,大家加油!

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/471326.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于 Python Django 的二手房间可视化系统分析

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

用MVVM设计模式提升WPF开发体验:分层架构与绑定实例解析

MVVM&#xff08;Model-View-ViewModel&#xff09;是一种架构模式&#xff0c;广泛应用于现代前端开发&#xff0c;尤其是在微软的WPF&#xff08;Windows Presentation Foundation&#xff09;应用程序中。它旨在通过将视图&#xff08;UI&#xff09;与业务逻辑&#xff08;…

如何进行产线高阶能耗数据的计算和可视化?

一、前言 在当前经济下行时期&#xff0c;越来越来多企业开始对产线进行数字化转型&#xff0c;提高企业竞争力。在产线数字化转型过程中&#xff0c;产线高阶能耗数据的计算和可视化是比较重要的一环&#xff0c;今天小编就和大家分享如何对产线能耗数据进行计算和可视化。 …

亲测有效:Maven3.8.1使用Tomcat8插件启动项目

我本地maven的settings.xml文件中的配置&#xff1a; <mirror><id>aliyunmaven</id><mirrorOf>central</mirrorOf><name>阿里云公共仓库</name><url>https://maven.aliyun.com/repository/public</url> </mirror>…

开源项目推荐——OpenDroneMap无人机影像数据处理

实景三维作为GIS最火的课题&#xff0c;最近在想做一套自己的三维构建工具&#xff0c;考察了几个开源项目&#xff0c;把自己的搜索过程用csdn记录下来&#xff0c;希望也能帮助到各位同仁。 OpenDroneMap&#xff08;ODM&#xff09;是一个开源项目&#xff0c;旨在处理无人…

蓝桥杯c++算法学习【2】之搜索与查找(九宫格、穿越雷区、迷宫与陷阱、扫地机器人:::非常典型的必刷例题!!!)

别忘了请点个赞收藏关注支持一下博主喵&#xff01;&#xff01;&#xff01; 关注博主&#xff0c;更多蓝桥杯nice题目静待更新:) 搜索与查找 一、九宫格 【问题描述】 小明最近在教邻居家的小朋友小学奥数&#xff0c;而最近正好讲述到了三阶幻方这个部分&#xff0c;三 …

Nuxt.js 应用中的 schema:beforeWrite 事件钩子详解

title: Nuxt.js 应用中的 schema:beforeWrite 事件钩子详解 date: 2024/11/14 updated: 2024/11/14 author: cmdragon excerpt: schema:beforeWrite 钩子是 Vite 提供的一个功能强大的生命周期钩子,允许开发者在 JSON Schema 被写入之前执行自定义操作。利用这个钩子,您可以…

当你想要conda安装遇到UnavailableInvalidChannel: HTTP 404 NOT FOUND for channel的问题

想要装个虚拟环境&#xff0c;结果遇到404。 看了第一个GitHub帖子中的一句话 UnavailableInvalidChannel: The channel is not accessible or is invalid. Navigator not launching. Issue #9473 conda/conda GitHub 想说那我就把这个not found的channel删掉吧&#xff…

DAY112代码审计PHP开发框架POP链利用Yii反序列化POP利用链

一、pop1链的跟踪 1、路由关系 2、漏洞触发口unserialize(base64_decode($data)); 2、__destruct()&#xff0c;魔术法方法调用close函数方法 3、未找到利用链&#xff0c;尝试__call魔术方法 4、逆推找call_user_func 函数 第一部分 namespace yii\db; class BatchQueryResu…

C++STL容器——map和set

目录 一.关联式容器 二.键值对 三.树形结构的关联式容器 1.set 2.map 3.multiset和multimap 四.整体代码 map_set.cpp 一.关联式容器 在初阶阶段&#xff0c;我们已经接触过STL中的部分容器&#xff0c;比如&#xff1a;vector、list、deque、 forward_list(C11)等&…

Java 责任链模式 减少 if else 实战案例

一、场景介绍 假设有这么一个朝廷&#xff0c;它有 县-->府-->省-->朝廷&#xff0c;四级行政机构。 这四级行政机构的关系如下表&#xff1a; 1、县-->府-->省-->朝廷&#xff1a;有些地方有完整的四级行政机构。 2、县-->府-->朝廷&#xff1a;直…

Rocky、Almalinux、CentOS、Ubuntu和Debian系统初始化脚本v9版

Rocky、Almalinux、CentOS、Ubuntu和Debian系统初始化脚本 Shell脚本源码地址&#xff1a; Gitee&#xff1a;https://gitee.com/raymond9/shell Github&#xff1a;https://github.com/raymond999999/shell脚本可以去上面的Gitee或Github代码仓库拉取。 支持的功能和系统&am…

EXCEL延迟退休公式

如图&#xff1a; A B为手工输入 C2EOMONTH(A2,B2*12) D2EOMONTH(C2,IF(C2>DATEVALUE("2025-1-1"),INT((DATEDIF(DATEVALUE("2025-1-1"),C2,"m")4)/4),0)) E2EOMONTH(A2,B2*12IF(EOMONTH(A2,B2*12)>DATEVALUE("2025-1-1"),INT(…

ARM架构中断与异常向量表机制解析

往期内容 本专栏往期内容&#xff0c;interrtupr子系统&#xff1a; 深入解析Linux内核中断管理&#xff1a;从IRQ描述符到irq domain的设计与实现Linux内核中IRQ Domain的结构、操作及映射机制详解中断描述符irq_desc成员详解Linux 内核中断描述符 (irq_desc) 的初始化与动态分…

论文翻译 | The Capacity for Moral Self-Correction in Large Language Models

摘要 我们测试了一个假设&#xff0c;即通过人类反馈强化学习&#xff08;RLHF&#xff09;训练的语言模型具有“道德自我纠正”的能力——避免产生有害的输出——如果指示这样做的话。我们在三个不同的实验中发现了支持这一假设的有力证据&#xff0c;每个实验都揭示了道德自…

华为云前台用户可挂载数据盘和系统盘是怎么做到的?

用户可以选择磁盘类型和容量&#xff0c;其后台是管理员对接存储设备 1.管理员如何在后台对接存储设备&#xff08;特指业务存储&#xff09; 1.1FusionSphere CPS&#xff08;Cloud Provisionivice&#xff09;云装配服务 它是first node https://10.200.4.159:8890 对接存…

【Excel】身份证号最后一位“X”怎么计算

大多数人身份证号最后一位都是数字&#xff0c;但有个别号码最后一位却是“X"。 如果你查百度&#xff0c;会得到如下答案&#xff1a; 当最后一位编码是10的时候&#xff0c;因为多出一位&#xff0c;所以就用X替换。 可大多数人不知道的是&#xff0c;这个10是怎么来的…

【常见问题解答】远程桌面无法复制粘贴的解决方法

提示:“奔跑吧邓邓子” 的常见问题专栏聚焦于各类技术领域常见问题的解答。涵盖操作系统(如 CentOS、Linux 等)、开发工具(如 Android Studio)、服务器软件(如 Zabbix、JumpServer、RocketMQ 等)以及远程桌面、代码克隆等多种场景。针对如远程桌面无法复制粘贴、Kuberne…

python解析网页上的json数据落地到EXCEL

安装必要的库 import requests import pandas as pd import os import sys import io import urllib3 import json测试数据 网页上的数据结构如下 {"success": true,"code": "CIFM_0000","encode": null,"message": &quo…

change buffer:到底应该选择普通索引还是唯一索引

文章目录 引言第一章&#xff1a;普通索引和唯一索引在查询逻辑与效率上的对比1.1 查询逻辑分析1.2 查询效率对比 第二章&#xff1a;普通索引和唯一索引在更新逻辑与效率上的对比2.1 更新逻辑分析2.2 更新效率对比 第三章&#xff1a;底层原理详解 - 普通索引和唯一索引的区别…