当前位置: 首页 > news >正文

双路快速排序和三路排序算法

双路快速排序

一、概念及其介绍

双路快速排序算法是随机化快速排序的改进版本,partition 过程使用两个索引值(i、j)用来遍历数组,将 <v 的元素放在索引i所指向位置的左边,而将 >v 的元素放在索引j所指向位置的右边,v 代表标定值。

二、适用说明

时间和空间复杂度同随机化快速排序。 对于有大量重复元素的数组,如果使用上一节随机化快速排序效率是非常低的,导致 partition 后大于基点或者小于基点数据的子数组长度会极度不平衡,甚至会退化成 O(n*2) 时间复杂度的算法,对这种情况可以使用双路快速排序算法。

三、过程

使用两个索引值(i、j)用来遍历我们的序列,将 <=v 的元素放在索引 i 所指向位置的左边,而将 >=v 的元素放在索引 j 所指向位置的右边,平衡左右两边子数组。

四、Java 实现分析

提供的Java代码实现了一个双路快速排序算法。以下是一些关键点的解释:

  • 随机选择标定点:为了减少最坏情况的发生概率,算法首先随机选择一个标定点,并将其与数组的第一个元素交换位置。这一步有助于提高算法的平均性能。

  • 分区函数 (partition):该函数实现了双路快速排序的核心逻辑。它使用两个指针 ij 来遍历数组,根据元素与标定点的关系调整指针位置,并在必要时交换元素。最终返回标定点的正确位置。

  • 递归排序sort 函数是一个递归函数,用于对数组的不同部分进行排序。每次调用 partition 函数后,都会得到一个新的标定点位置,然后对左右两部分分别进行递归排序。

  • 主函数 (main):这里创建了一个测试用例来验证算法的正确性和性能。通过生成一个大数组并调用 sort 方法对其进行排序,可以观察到双路快速排序在大数据量下的高效表现。

package runoob;/*** 双路快速排序*/
public class QuickSort2Ways {//核心代码---开始private static int partition(Comparable[] arr, int l, int r){// 随机在arr[l...r]的范围中, 选择一个数值作为标定点pivotswap( arr, l , (int)(Math.random()*(r-l+1))+l );Comparable v = arr[l];// arr[l+1...i) <= v; arr(j...r] >= vint i = l+1, j = r;while( true ){while( i <= r && arr[i].compareTo(v) < 0 )i ++;while( j >= l+1 && arr[j].compareTo(v) > 0 )j --;if( i > j )break;swap( arr, i, j );i ++;j --;}swap(arr, l, j);return j;}//核心代码---结束// 递归使用快速排序,对arr[l...r]的范围进行排序private static void sort(Comparable[] arr, int l, int r){if (l >= r) {return;}int p = partition(arr, l, r);sort(arr, l, p-1 );sort(arr, p+1, r);}public static void sort(Comparable[] arr){int n = arr.length;sort(arr, 0, n-1);}private static void swap(Object[] arr, int i, int j) {Object t = arr[i];arr[i] = arr[j];arr[j] = t;}// 测试 QuickSortpublic static void main(String[] args) {// 双路快速排序算法也是一个O(nlogn)复杂度的算法// 可以在1秒之内轻松处理100万数量级的数据// Quick Sort也是一个O(nlogn)复杂度的算法// 可以在1秒之内轻松处理100万数量级的数据int N = 1000000;Integer[] arr = SortTestHelper.generateRandomArray(N, 0, 100000);sort(arr);SortTestHelper.printArray(arr);}
}

三路排序算法

一、概念及其介绍

三路快速排序是双路快速排序的进一步改进版本,三路排序算法把排序的数据分为三部分,分别为小于 v,等于 v,大于 v,v 为标定值,这样三部分的数据中,等于 v 的数据在下次递归中不再需要排序,小于 v 和大于 v 的数据也不会出现某一个特别多的情况),通过此方式三路快速排序算法的性能更优。

二、适用说明

时间和空间复杂度同随机化快速排序。

三路快速排序算法是使用三路划分策略对数组进行划分,对处理大量重复元素的数组非常有效提高快速排序的过程。它添加处理等于划分元素值的逻辑,将所有等于划分元素的值集中在一起。

三、过程

我们分三种情况进行讨论 partiton 过程,i 表示遍历的当前索引位置:

(1)当前处理的元素 e=V,元素 e 直接纳入蓝色区间,同时i向后移一位。

(2)当前处理元素 e<v,e 和等于 V 区间的第一个位置数值进行交换,同时索引 lt 和 i 都向后移动一位

(3)当前处理元素 e>v,e 和 gt-1 索引位置的数值进行交换,同时 gt 索引向前移动一位。

最后当 i=gt 时,结束遍历,同时需要把 v 和索引 lt 指向的数值进行交换,这样这个排序过程就完成了,然后对 <V 和 >V 的数组部分用同样的方法再进行递归排序。

假设有一个数组 [2, 5, 2, 3, 7, 5, 5, 2],标定点 v5

  1. 初始状态:lt = 0, i = 1, gt = 8

    • 数组:[2, 5, 2, 3, 7, 5, 5, 2]
  2. 遍历过程:

    • 当 i = 1 时,arr[i] == vi 向前移动一位:i = 2
    • 当 i = 2 时,arr[i] < v,交换 arr[2] 和 arr[lt+1]lt 和 i 前进:lt = 1i = 3
      • 数组:[2, 2, 5, 3, 7, 5, 5, 2]
    • 当 i = 3 时,arr[i] < v,交换 arr[3] 和 arr[lt+1]lt 和 i 前进:lt = 2i = 4
      • 数组:[2, 2, 3, 5, 7, 5, 5, 2]
    • 当 i = 4 时,arr[i] > v,交换 arr[4] 和 arr[gt-1]gt 向前移动:gt = 7
      • 数组:[2, 2, 3, 5, 5, 5, 7, 2]
    • 当 i = 4 时,arr[i] == vi 向前移动一位:i = 5
    • 当 i = 5 时,arr[i] == vi 向前移动一位:i = 6
    • 当 i = 6 时,arr[i] > v,交换 arr[6] 和 arr[gt-1]gt 向前移动:gt = 6
      • 数组:[2, 2, 3, 5, 5, 5, 2, 7]
    • 当 i = 6 时,i == gt,遍历结束。
  3. 最后,将标定点 5lt 指向的元素交换:lt = 3

    • 数组:[2, 2, 3, 5, 5, 5, 2, 7]

四、Java 实例代码

package runoob;/*** 三路快速排序*/
public class QuickSort3Ways {//核心代码---开始// 递归使用快速排序,对arr[l...r]的范围进行排序private static void sort(Comparable[] arr, int l, int r){if (l >= r) {return;}// 随机在arr[l...r]的范围中, 选择一个数值作为标定点pivotswap( arr, l, (int)(Math.random()*(r-l+1)) + l );Comparable v = arr[l];int lt = l;     // arr[l+1...lt] < vint gt = r + 1; // arr[gt...r] > vint i = l+1;    // arr[lt+1...i) == vwhile( i < gt ){if( arr[i].compareTo(v) < 0 ){swap( arr, i, lt+1);i ++;lt ++;}else if( arr[i].compareTo(v) > 0 ){swap( arr, i, gt-1);gt --;}else{ // arr[i] == vi ++;}}swap( arr, l, lt );sort(arr, l, lt-1);sort(arr, gt, r);}//核心代码---结束public static void sort(Comparable[] arr){int n = arr.length;sort(arr, 0, n-1);}private static void swap(Object[] arr, int i, int j) {Object t = arr[i];arr[i] = arr[j];arr[j] = t;}// 测试 QuickSort3Wayspublic static void main(String[] args) {// 三路快速排序算法也是一个O(nlogn)复杂度的算法// 可以在1秒之内轻松处理100万数量级的数据int N = 1000000;Integer[] arr = SortTestHelper.generateRandomArray(N, 0, 100000);sort(arr);SortTestHelper.printArray(arr);}
}

排序算法衍生问题

本小节对本教程的排序算法做一个总结。

(1)归并排序和快速排序都使用了分治算法。

顾名思义,就是将原问题分割查能同等结构的子问题,之后将子问题逐一解决后,原问题也就得到了解决。

(2)逆序对的定义

如果存在正整数 i, j 使得 1 ≤ i < j ≤ n 而且 A[i] > A[j],则 <A[i], A[j]> 这个有序对称为 A 的一个逆序对。我们可以使用本教程的归并思想求逆序对的数量。

(3)取数组中第 n 大的元素

并不需要对整个数组进行排序,使用快速排序的思路求数组中第 n 大元素算法复杂度为 O(n)。

相关文章:

双路快速排序和三路排序算法

双路快速排序 一、概念及其介绍 双路快速排序算法是随机化快速排序的改进版本&#xff0c;partition 过程使用两个索引值&#xff08;i、j&#xff09;用来遍历数组&#xff0c;将 <v 的元素放在索引i所指向位置的左边&#xff0c;而将 >v 的元素放在索引j所指向位置的…...

SQL server增删改查语句和实例

在 SQL Server 中&#xff0c;增删改查操作分别对应 INSERT、DELETE、UPDATE 和 SELECT 语句。以下是具体介绍及实例&#xff1a; 一、插入数据&#xff08;INSERT&#xff09; 语法&#xff1a; INSERT INTO table_name (column1, column2, column3,...) VALUES (value1, val…...

强化学习_06_pytorch-PPO2实践(ALE/Breakout-v5)

一、环境适当调整 数据收集&#xff1a;RecordEpisodeStatistics进行起始跳过n帧&#xff1a;baseSkipFrame一条生命结束记录为done:EpisodicLifeEnv得分处理成0或1:ClipRewardEnv叠帧: FrameStack 图像环境的基本操作&#xff0c;方便CNN捕捉智能体的行动 向量空间reset处理修…...

《JVM第8课》垃圾回收算法

文章目录 1.标记算法1.1 引用计数法1.2 可达性分析法 2.回收算法2.1 标记-清除算法&#xff08;Mark-Sweep&#xff09;2.2 复制算法&#xff08;Coping&#xff09;2.3 标记-整理算法&#xff08;Mark-Compact&#xff09; 3.三种垃圾回收算法的对比 为什么要进行垃圾回收&…...

SpringBoot整合Freemarker(二)

if分支 语法&#xff1a; <#if condition>... <#elseif condition2>... <#elseif condition3>... <#else>... </#if> 例子&#xff1a; <#if x 1>x is 1 </#if> --------------------------------- <#if x 1>x is 1 <…...

element plus el-form自定义验证输入框为纯数字函数

element plus 的el-form 使用自定义验证器&#xff0c;验证纯数字&#xff0c;禁止输入小数、中文、字母、特殊符号。input的maxlength为最大输入多少位长度 效果图 <el-form ref"dataFormRef" :model"dataForm" :rules"dataRules" label-w…...

Android笔记(三十一):Deeplink失效问题

背景 通过deeplink启动应用之后&#xff0c;没关闭应用的情况下&#xff0c;再次使用deeplink会失效的问题&#xff0c;是系统bug导致的。此bug仅在某些设备&#xff08;Nexus 5X&#xff09;上重现&#xff0c;launchMode并且仅当应用程序最初通过深层链接启动并再次通过深层…...

图神经网络初步实验

实验复现来源 https://zhuanlan.zhihu.com/p/603486955 该文章主要解决问题&#xff1a; 1.加深对图神经网络数据集的理解 2.加深对图神经网络模型中喂数据中维度变化的理解 原理问题在另一篇文章分析&#xff1a; 介绍数据集&#xff1a;cora数据集 其中的主要内容表示为…...

创建线程时传递参数给线程

在C中&#xff0c;可以使用 std::thread 来创建和管理线程&#xff0c;同时可以通过几种方式将参数传递给线程函数。这些方法包括使用值传递、引用传递和指针传递。下面将对这些方法进行详细讲解并给出相应的代码示例。 1. 值传递参数 当你创建线程并希望传递参数时&#xff…...

兴业严选|美国总统都是不良资产出身 法拍市场是否将大众化

北京时间11月6日&#xff0c;特朗普赢得美国大选。 说起特朗普那就不得不提他的发家史&#xff0c;那可真是一笔笔不良资产投资堆出来的。 没错&#xff0c;特朗普就是处理不良资产的高手&#xff0c;战果丰硕。 改造斯威夫特小镇、 康莫德酒店、打造特朗普&#xff08;TRUM…...

C#-拓展方法

概念&#xff1a;为现有的非静态变量类型&#xff0c;添加方法 语法&#xff1a; 访问修饰符 static 返回值 函数名(this 拓展类名 参数名, 参数类型 参数名,参数类型 参数名....){} 而public static void F(this Console()){ }是错的。Console是静态类不可以为静态类添加方…...

加锁失效,非锁之过,加之错也|京东零售供应链库存研发实践

本文导读 从事京东零售供应链库存业务&#xff0c;库存数量操作增减十分频繁&#xff0c;并且项目开发中会常常遇到各种并发情况&#xff0c;一旦库存数量操作有误&#xff0c;势必给前台销售产生损失影响&#xff0c;因此需要关注对库存数量并发操作下的一致性问题。 大部分…...

vue3 传值的几种方式

一.父组件传子组件 父组件 //父组件 <Decisionobject :Decisionselected"Decisionselected"></Decisionobject> <script lang"ts" setup> let Decisionselected ref(false); </script>子组件 <script lang"ts" s…...

AUTOSAR CP NVRAM Manager规范导读

一、NVRAM Manager功能概述 NVRAM Manager是AUTOSAR(AUTomotive Open System ARchitecture)框架中的一个模块,负责管理非易失性随机访问存储器(NVRAM)。它提供了一组服务和API,用于在汽车环境中存储、维护和恢复NV数据。以下是NVRAM Manager的一些关键功能: 数据存储和…...

2024阿里云CTF Web writeup

《Java代码审计》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484219&idx1&sn73564e316a4c9794019f15dd6b3ba9f6&chksmc0e47a67f793f371e9f6a4fbc06e7929cb1480b7320fae34c32563307df3a28aca49d1a4addd&scene21#wechat_redirect 前言 又是周末…...

软件著作权申请教程(超详细)(2024新版)软著申请

目录 一、注册账号与实名登记 二、材料准备 三、申请步骤 1.办理身份 2.软件申请信息 3.软件开发信息 4.软件功能与特点 5.填报完成 一、注册账号与实名登记 首先我们需要在官网里面注册一个账号&#xff0c;并且完成实名认证&#xff0c;一般是注册【个人】的身份。中…...

三维测量与建模笔记 - 3.2 直接线性变换法标定DLT

DLT - Direct Linear Transform 上图中&#xff0c;透视成像对应的公式是共线方程&#xff0c;可以参考以下链接&#xff1a; https://zhuanlan.zhihu.com/p/101549821https://zhuanlan.zhihu.com/p/101549821 对于标定来说&#xff0c;需要找到。已知量是。 (u,v)是…...

Whisper AI视频(音频)转文本

在信息化时代&#xff0c;如何高效处理丰富的音频和视频内容成为了一个重要课题。将这些内容转化为文本不仅能提高信息的可获取性&#xff0c;还能促进更广泛的传播。Whisper Desktop作为一款先进的语音识别工具&#xff0c;能够帮助用户轻松实现音频和视频的转文本功能。 什么…...

全网最详细RabbitMQ教学包括如何安装环境【RabbitMQ】RabbitMQ + Spring Boot集成零基础入门(基础篇)

目录 一、初始Rabbitmq1、什么是Rabbitmq&#xff0c;它的概述是什么&#xff1f;2、RabbitMQ的应用场景3、RabbitMQ主要组件4、RabbitMQ 的优点5、与其他消息队列性能比较 二、RabbitMQ环境安装初始化三、SpringAMQPRabbitMQ实战入门&#xff08;基本API&#xff09;1、实战入…...

esp32记录一次错误

报错信息 PS C:\XingNian\GeRen\4Gdownload\wireless-esp8266-dap> idf.py build Executing action: all (aliases: build) Running cmake in directory c:\xingnian\geren\4gdownload\wireless-esp8266-dap\build Executing "cmake -G Ninja -DPYTHON_DEPS_CHECKED1 …...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

【Java_EE】Spring MVC

目录 Spring Web MVC ​编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 ​编辑参数重命名 RequestParam ​编辑​编辑传递集合 RequestParam 传递JSON数据 ​编辑RequestBody ​…...

2023赣州旅游投资集团

单选题 1.“不登高山&#xff0c;不知天之高也&#xff1b;不临深溪&#xff0c;不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

Linux系统部署KES

1、安装准备 1.版本说明V008R006C009B0014 V008&#xff1a;是version产品的大版本。 R006&#xff1a;是release产品特性版本。 C009&#xff1a;是通用版 B0014&#xff1a;是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存&#xff1a;1GB 以上 硬盘&#xf…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

boost::filesystem::path文件路径使用详解和示例

boost::filesystem::path 是 Boost 库中用于跨平台操作文件路径的类&#xff0c;封装了路径的拼接、分割、提取、判断等常用功能。下面是对它的使用详解&#xff0c;包括常用接口与完整示例。 1. 引入头文件与命名空间 #include <boost/filesystem.hpp> namespace fs b…...

32位寻址与64位寻址

32位寻址与64位寻址 32位寻址是什么&#xff1f; 32位寻址是指计算机的CPU、内存或总线系统使用32位二进制数来标识和访问内存中的存储单元&#xff08;地址&#xff09;&#xff0c;其核心含义与能力如下&#xff1a; 1. 核心定义 地址位宽&#xff1a;CPU或内存控制器用32位…...

以太网PHY布局布线指南

1. 简介 对于以太网布局布线遵循以下准则很重要&#xff0c;因为这将有助于减少信号发射&#xff0c;最大程度地减少噪声&#xff0c;确保器件作用&#xff0c;最大程度地减少泄漏并提高信号质量。 2. PHY设计准则 2.1 DRC错误检查 首先检查DRC规则是否设置正确&#xff0c;然…...

CentOS 7.9安装Nginx1.24.0时报 checking for LuaJIT 2.x ... not found

Nginx1.24编译时&#xff0c;报LuaJIT2.x错误&#xff0c; configuring additional modules adding module in /www/server/nginx/src/ngx_devel_kit ngx_devel_kit was configured adding module in /www/server/nginx/src/lua_nginx_module checking for LuaJIT 2.x ... not…...

数据可视化交互

目录 【实验目的】 【实验原理】 【实验环境】 【实验步骤】 一、安装 pyecharts 二、下载数据 三、实验任务 实验 1&#xff1a;AQI 横向对比条形图 代码说明&#xff1a; 运行结果&#xff1a; 实验 2&#xff1a;AQI 等级分布饼图 实验 3&#xff1a;多城市 AQI…...