快速排序算法的递归和非递归
基本思路
选择一个基准值,将数组划分三个区域,小于基准值的区域位于左侧,等于基准值的区域位于中间,大于基准值的区域位于右侧。将大于和小于区域继续进行分区,周而复始,不断进行分区和交换,直到排序完成
递归
思路:
步骤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实例 🫐产品优势 🥝…...

Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
JS手写代码篇----使用Promise封装AJAX请求
15、使用Promise封装AJAX请求 promise就有reject和resolve了,就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...

mac:大模型系列测试
0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何,是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试,是可以跑通文章里面的代码。训练速度也是很快的。 注意…...

Qt的学习(一)
1.什么是Qt Qt特指用来进行桌面应用开发(电脑上写的程序)涉及到的一套技术Qt无法开发网页前端,也不能开发移动应用。 客户端开发的重要任务:编写和用户交互的界面。一般来说和用户交互的界面,有两种典型风格&…...

spring boot使用HttpServletResponse实现sse后端流式输出消息
1.以前只是看过SSE的相关文章,没有具体实践,这次接入AI大模型使用到了流式输出,涉及到给前端流式返回,所以记录一下。 2.resp要设置为text/event-stream resp.setContentType("text/event-stream"); resp.setCharacter…...