当前位置: 首页 > 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 …...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

高防服务器价格高原因分析

高防服务器的价格较高&#xff0c;主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因&#xff1a; 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器&#xff0c;因此…...

32位寻址与64位寻址

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