快速排序算法的递归和非递归
基本思路
选择一个基准值,将数组划分三个区域,小于基准值的区域位于左侧,等于基准值的区域位于中间,大于基准值的区域位于右侧。将大于和小于区域继续进行分区,周而复始,不断进行分区和交换,直到排序完成
递归
思路:
步骤1:
在当前分区范围[l,r]中随机选中一个数作为基准值,交换到分区范围的最右侧,即r位置
步骤2:
以r位置基准值进行分区
步骤3:
对所以小于区域和大于区域继续进行步骤1操作,直到范围为1结束
单次分区过程:
less 代表小于基准值分区范围,more代表大于分区值范围,index代表当前待比较位置,r为当前分区范围最右位置
比较当前index位置和基准位置
如果 arr[index] == arr[r] ,则index向右移动
如果大于,则 more向左移动,并将index位置的数与more位置的数进行交换
如果小于,则将 less右侧位置的数与index数交换;即less范围扩大 less++,交换less和index位置数,index右移

code:
//递归public static void quickSortRecursive(int [] arr){if(arr == null || arr.length < 2)return;progress(arr,0,arr.length-1);}//让arr在[l,r]上有序public static void progress(int [] arr,int l,int r){if(l >= r){return;}//swap(arr, L + (int) (Math.random() * (R - L + 1)), R);//指定一个[l,r]范围随机位置放到最右侧作为基准值// math.random: [0,1)// math.random * x : [0,x)// Math.random() * (r -l + 1) : l到r长度范围内的一个随机数, + l则定位到数组的索引上swap(arr,l + (int)(Math.random() * (r -l + 1)),r);int [] equalArea = partition(arr,l,r);progress(arr,l,equalArea[0] -1);progress(arr,equalArea[1] + 1,r);}
//让arr以r位置数为基准,<arr[r]位置的数放左边,>arr[r]位置的数放右边 ==arr[r]位置的数位于中间//返回==arr[r]位置的数最左和最右位置public static int[] partition(int [] arr,int l,int r){//如果l > r,则数组不合规,返回一个无效值索引if(l > r) return new int[] { -1, -1 };//如果l == r,则说明只有一个值,那么等于分区也就是当前一个位置的索引if(l == r) return new int[] {l,r};//l < r//基准位置 r//less代表 <分区 的最右一个位置索引int less = l -1;//more代表 >分区 的最左一个位置的索引int more = r;//index代表待分区数最左位置索引int index = l;//进行分区,越界条件是待分区索引来到以分区区域[大于分区]while (index < more){//System.out.println("less,index,more:"+less+","+index + ","+more);//如果待分区数 == 基准值,那么说明该数不是大于分区的数,index向右移动if(arr[index] == arr[r]){index++;}//如果待分区数 < 基准值,那么说明该位置数是属于小于分区的数,则将该数交换到小于分区去if(arr[index] < arr[r]){//小于分区范围扩大less++;//将当前位置交换到小于分区//此时当前位置是等于或者小于分区的数swap(arr,index,less);//索引index需要向右移动index++;//等价于//swap(arr,index++,++less);}//如果待分区数 > 基准值,那么说明该位置数是属于大于分区的数,则将该数交换到大于分区去//此时index不移动,因为将位置的数交换到index位置上了if(arr[index] > arr[r]){//大于范围向左扩张more--;//当前数交换到大于区域中,交换来的数是一个未知大小的数,所以index不移动swap(arr,index,more);//等价于//swap(arr,index,--more);}}//遍历完成后,此时r位置为等于区域的数,需要交换到等于分区中swap(arr,more,r);//交换完成后,less为小于分区最右索引,more为等于分区最右索引//more原本为大于分区最左位置索引,但是将r交换到该位置后,大于分区向右缩减了一个位置,此时more位置为等于分区最右索引return new int[]{less+1,more};}public static void swap(int [] arr,int l,int r){int temp = arr[l];arr[l] = arr[r];arr[r] = temp;}
非递归
思路与递归一致,仅是将系统栈替换为自己控制的栈
使用栈记录每次分区得到的左右位置
然后出栈顶元素,继续分区,将新的分区如栈,直到栈为空
使用一个辅助对象用于入栈时保存分区位置 op
code:
//非递归版//使用栈记录每次分区得到的左右位置//然后出栈顶元素,继续分区,将新的分区如栈,直到栈为空//使用一个辅助对象用于入栈时保存分区位置 oppublic static void quickSortUnRecursive(int [] arr){if(arr == null || arr.length < 2) return;int N = arr.length;Stack<Op> stack = new Stack<>();//随机得到基准值,放到最右位置swap(arr, (int)(Math.random() * N),N-1);//分区int [] equalArea = partition(arr,0,N-1);//将分区后的范围入栈stack.push(new Op(0,equalArea[0] -1));stack.push(new Op(equalArea[1]+1,N-1));//临时变量,保存出栈的范围值Op temp = new Op(0,0);while (!stack.isEmpty()){//出栈temp = stack.pop();//继续对当前范围进行分区//如果分区得到的范围错误,说明该区域已经排好序了if(temp.l >= temp.r)continue;//随机基准值swap(arr,temp.l + (int) (Math.random() * (temp.r - temp.l + 1)), temp.r);//分区equalArea = partition(arr,temp.l, temp.r);//入栈stack.push(new Op(temp.l, equalArea[0] -1));stack.push(new Op(equalArea[1]+ 1, temp.r));}}public static class Op{public int l;public int r;public Op(int l,int r){this.l = l;this.r = r;}}//让arr以r位置数为基准,<arr[r]位置的数放左边,>arr[r]位置的数放右边 ==arr[r]位置的数位于中间//返回==arr[r]位置的数最左和最右位置public static int[] partition(int [] arr,int l,int r){//如果l > r,则数组不合规,返回一个无效值索引if(l > r) return new int[] { -1, -1 };//如果l == r,则说明只有一个值,那么等于分区也就是当前一个位置的索引if(l == r) return new int[] {l,r};//l < r//基准位置 r//less代表 <分区 的最右一个位置索引int less = l -1;//more代表 >分区 的最左一个位置的索引int more = r;//index代表待分区数最左位置索引int index = l;//进行分区,越界条件是待分区索引来到以分区区域[大于分区]while (index < more){//System.out.println("less,index,more:"+less+","+index + ","+more);//如果待分区数 == 基准值,那么说明该数不是大于分区的数,index向右移动if(arr[index] == arr[r]){index++;}//如果待分区数 < 基准值,那么说明该位置数是属于小于分区的数,则将该数交换到小于分区去if(arr[index] < arr[r]){//小于分区范围扩大less++;//将当前位置交换到小于分区//此时当前位置是等于或者小于分区的数swap(arr,index,less);//索引index需要向右移动index++;//等价于//swap(arr,index++,++less);}//如果待分区数 > 基准值,那么说明该位置数是属于大于分区的数,则将该数交换到大于分区去//此时index不移动,因为将位置的数交换到index位置上了if(arr[index] > arr[r]){//大于范围向左扩张more--;//当前数交换到大于区域中,交换来的数是一个未知大小的数,所以index不移动swap(arr,index,more);//等价于//swap(arr,index,--more);}}//遍历完成后,此时r位置为等于区域的数,需要交换到等于分区中swap(arr,more,r);//交换完成后,less为小于分区最右索引,more为等于分区最右索引//more原本为大于分区最左位置索引,但是将r交换到该位置后,大于分区向右缩减了一个位置,此时more位置为等于分区最右索引return new int[]{less+1,more};}public static void swap(int [] arr,int l,int r){int temp = arr[l];arr[l] = arr[r];arr[r] = temp;}
相关文章:
快速排序算法的递归和非递归
基本思路 选择一个基准值,将数组划分三个区域,小于基准值的区域位于左侧,等于基准值的区域位于中间,大于基准值的区域位于右侧。将大于和小于区域继续进行分区,周而复始,不断进行分区和交换,直…...
Maven无法拉取SNAPSHOT依赖的解决办法
背景 自己所在的部门主要是为其他项目组提供基础组件,如果需要使用新特性,其他项目组还会经常引用SNAPSHOT版本的组件进行开发测试。平时自己做测试的时候,因为手里有源码,所以每次都是先执行 mvn install 在本地安装后ÿ…...
day16-面向对象综合练习(上)
1. 设计游戏的目的 锻炼逻辑思维能力利用Java的图形化界面,写一个项目,知道前面学习的知识点在实际开发中的应用场景 2. 游戏的最终效果呈现 Hello,各位同学大家好。今天,我们要写一个非常有意思的小游戏 —《拼图小游戏》 我们…...
在Windos 10专业版搭建Fyne(Go 跨平台GUI)开发环境
目录 在Windos 10专业版搭建Fyne(Go 跨平台GUI)开发环境一 Fyne 和 MSYS2简介1.1 Fyne1.2 MSYS2 二 安装 MSYS22.1 下载MSYS22.2 安装2.3 环境变量设置2.4 检测安装环境 三 参考文档 在Windos 10专业版搭建Fyne(Go 跨平台GUI)开发…...
漫谈:C、C++字符串的困局
由于历史的原因,C、C字符串是个很让程序员头疼的东西。 字符串被解读为字符数组,但是又不等价于字符数组,而是带有附加的结束符的字符数组。 结束符‘\0’也是一个字符,但是又不计算在字符串长度里面(strlen࿰…...
基于python+selenium的自动批量添加
场景 点击添加”新增“按钮,弹出”新增对话框“,输入各种数据,然后点击”确定“按钮,如此循环。数量多,这样操作累人。 selenium Selenium 是一个用于自动化 Web 浏览器操作的库,可以实现模拟点击、输入…...
gdb监视
怀疑踩内存了,如何利用gdb监视一段内存的值 在实际情况中,如果怀疑一个进程中的变量被踩内存了,但是不知道什么时候会被踩,就可以用下面的方法进行debug。GDB(GNU Debugger)是一个功能强大的调试工具&…...
STM32基础知识点总结
一、基础知识点 1、课程体系介绍 单片机概述arm体系结构STM32开发环境搭建 STM32-GPIO编程-点亮世界的那盏灯 STM32-USART串口应用SPI液晶屏 STM32-中断系统 STM32-时钟系统 STM32-ADC DMA 温湿度传感器-DHT11 2.如何学习单片机课程 多听理论、多理解、有问题及时提问 自己多…...
Python vs C#:首先学习哪种编程语言最好?
进入编码可能很困难。 最艰难的部分? 决定先学什么语言。 当谈到 Python 与 C# 时,可能很难知道在您的决定中要考虑哪些因素。 我们为您提供了有关这些全明星编程语言的所有信息。 什么是 C#? 自 2000 年作为 Microsoft Visual Studio 的一部分开发 C# 以来,它一直是开发人…...
代理IP和Socks5代理:跨界电商与全球爬虫的关键技术
跨界电商在全球化市场中崭露头角,而代理IP和Socks5代理则成为实现全球市场洞察和数据采集的不可或缺的工具。本文将深入探讨这两种代理技术在跨界电商、爬虫技术和出海战略中的关键作用。 引言: 介绍跨界电商的崛起和全球市场的机遇与挑战。引出代理IP…...
CentOS 7 调优之周期性的访问中断
文章目录 背景问题描述原因分析解决方案相关版本 背景 操作系统版本:CentOS Linux release 7.6.1810 (Core) 操作系统镜像安装后,未进行任何调整。正常部署应用,应用在 CentOS 7.9 未出现过此类现象。 问题描述 问题描述:负载教…...
SpringBoot表现层数据一致性
1.定义Restful类 说明:使用Data注解是Lombok库提供的一个注解,用于自动生成类的getter、setter、equals、hashcode和toString方法。 package com.forever.controller.utils;import lombok.Data;Data public class Restful {private Boolean flag;//dat…...
vue路由-两个树形结构数据-递归处理方法
1.vue静态路由 const dynamicRoutes [{path: /,name: /,component: () > import(//layout/index.vue),redirect: /home,meta: {isKeepAlive: true,},children: [{path: /home,name: home,component: () > import(//views/home/index.vue),meta: {title: 首页,isLink: ,…...
JSP SSM 成果展示系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计
一、源码特点 JSP SSM 冬奥建设成果展示系统是一套完善的web设计系统(系统采用SSM框架进行设计开发,springspringMVCmybatis),对理解JSP java编程开发语言有帮助,系统具有完整的 源代码和数据库,系统主…...
脚本:python绘制七夕爱心
文章目录 效果脚本Reference 效果 脚本 import random from math import sin, cos, pi, log from tkinter import *CANVAS_WIDTH 640 # 画布的宽 CANVAS_HEIGHT 640 # 画布的高 CANVAS_CENTER_X CANVAS_WIDTH / 2 # 画布中心的X轴坐标 CANVAS_CENTER_Y CANVAS_HEIGHT /…...
L1 项目概述与Hadoop部署
1.技术栈:HadoopHiveSqoopFlumeAzkaban Flume采集Nginx web服务器上的日志,采集完成后存储到Hadoop的平台,最终存储到HDFS上,处理和分析采用Hive的方式,处理完之后利用Sqoop导出到Mysql中,最终利用一个Java…...
关键词文章生成器-标题文章生成器
那就是如何在根据标题生成文章和根据关键词生成文章之间找到平衡之道。在这个信息时代,内容创作已经成为了一项重要的工作,无论是博客作者、社交媒体达人还是企业宣传,都需要不断地输出优质的内容。但是,我们常常陷入一个两难的困…...
深入了解MySQL中的JSON_ARRAYAGG和JSON_OBJECT函数
在MySQL数据库中,JSON格式的数据处理已经变得越来越常见。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它可以用来存储和表示结构化的数据。MySQL提供了一些功能强大的JSON函数,其中两个关键的函数是…...
Ubuntu22.04开启后屏幕黄屏
1. 故障现象 系统:Ubuntu22.04 现象:电脑从开机到进入桌面一直屏幕黄屏 2. 故障分析 可能为屏幕色彩调节出现故障 3. 解决方案 系统设置——》色彩——》删除原来的配置(remove profile)——》添加配置Colorspace:Compatibl…...
华为云云耀云服务器L实例评测 | 搭建docker环境
目录 🍒docker的概念 🍒Docker 的优点 🫐1、快速,一致地交付您的应用程序 🫐2、响应式部署和扩展 🫐3、在同一硬件上运行更多工作负载 🍒云耀云服务器L实例 🫐产品优势 🥝…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7
在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤: 第一步: 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为: // 改为 v…...
MeanFlow:何凯明新作,单步去噪图像生成新SOTA
1.简介 这篇文章介绍了一种名为MeanFlow的新型生成模型框架,旨在通过单步生成过程高效地将先验分布转换为数据分布。文章的核心创新在于引入了平均速度的概念,这一概念的引入使得模型能够通过单次函数评估完成从先验分布到数据分布的转换,显…...
【向量库】Weaviate 搜索与索引技术:从基础概念到性能优化
文章目录 零、概述一、搜索技术分类1. 向量搜索:捕捉语义的智能检索2. 关键字搜索:精确匹配的传统方案3. 混合搜索:语义与精确的双重保障 二、向量检索技术分类1. HNSW索引:大规模数据的高效引擎2. Flat索引:小规模数据…...
电脑定时关机工具推荐
软件介绍 本文介绍一款轻量级的电脑自动关机工具,无需安装,使用简单,可满足定时关机需求。 工具简介 这款关机助手是一款无需安装的小型软件,文件体积仅60KB,下载后可直接运行,无需复杂配置。 使用…...

