快速排序原理解析(简单易懂图文代码配套)
什么是快速排序
通冒泡排序一样,快速排序也属于叫唤排序,通过元素之间的比较和交换来达到目的。不同的是,冒泡排序在每一轮中只把1个元素冒泡到数列另一端,而快排则在每一轮挑选一个基准元素,并让其他比他大的元素移到数列一边,比它小的移到另一边,相当是把数列拆成了两个部分。这种思路其实叫分治法。
选定基准元素(pivot)
在分治过程中,以基准元素为中心,把其它元素移动到它的左右两边。那么怎么选基准元素呢?最简单的就是选数列第一个元素。还有就是随机选择数列中一个元素。不过都存在一个问题就是选的基准元素会是数列中最小的或者最大的值,在这种极端情况下,快速排序需要进行N轮,时间复杂度就退化成了O(n^2),不过平均时间复杂度还是保持在O(nlogn)。
元素交换排序过程
一、双边循环法:数组两边交换遍历元素。
选出基准元素pivot,确定2个指针left跟right
- right指针开始,right指向元素跟基准元素比较,如果大于或等于pivot,指针向左移动。小于基准则停止移动,切换到left指针。
- left指针移动,跟基准元素比较,如果小于等于pivot,指针向右移动,如果大于pivot,指针停止移动。
- 由于6>3,left在元素6的位置停下,让left与right指针所指向的元素进行交换。
按照此方法,一直循环比交换。
当循环到right指针和left指针重合的时候跟pivot基准元素交换。进行下一轮循环交换。
代码递归实现:
private static void quickSort(int[] arr,int startIndex,int endIndex){//递归结束条件if (startIndex >= endIndex){return;}//得到基准元素int pivotIndex = partition(arr,startIndex,endIndex);//根基基准元素,分成两部分进行递归排序quickSort(arr,startIndex,pivotIndex-1);quickSort(arr,pivotIndex+1,endIndex);}/*** 双边循环法* @param arr 待交换数组* @param startIndex 起始下标* @param endIndex 结束下标* @return left*/private static int partition(int[] arr, int startIndex, int endIndex) {//取第一个元素也可以随机取作为基准元素int pivot = arr[startIndex];int left = startIndex;int right = endIndex;while (left != right){//控制right指针比较并左移while (left<right && arr[right]> pivot){right--;}//控制left指针比较并右移while (left<right && arr[left] <= pivot){left++;}//交换left和right指针指向的元素if (left<right){int temp = arr[left];arr[left] = arr[right];arr[right] = temp;}}//pivot和指针重复交换arr[startIndex] = arr[left];arr[left] = pivot;return left;}public static void main(String[] args) {int[] arr = {4,7,2,5,6,1,8};quickSort(arr,0,arr.length-1);System.out.println(Arrays.toString(arr));}
二、单边循环法:从数组一边对元素遍历交换元素。
选定基准元素pivot,设置mark指针指向数组起始位置,mark指针代表小于基准元素的区域边界。
1、从基准元素的下一个位置开始遍历数组。如果遍历到的大于基准,就继续向后遍历。
2、如果遍历到的小于基准,需要做两件事:
- 把mark指针右移一位。
- 最近遍历到的与mark指针所在位置元素交换位置。
如图遍历到的是2>3,所以mark右移一位到2元素上面。在跟3元素交换位置得到下图。
接下来依照以上方法一直交换到顺序排列位置。
代码递归实现:
private static void quickSort(int[] arr,int startIndex,int endIndex){//递归结束条件if (startIndex >= endIndex){return;}//得到基准元素int pivotIndex = partition(arr,startIndex,endIndex);//根基基准元素,分成两部分进行递归排序quickSort(arr,startIndex,pivotIndex-1);quickSort(arr,pivotIndex+1,endIndex);}/*** 单边循环法* @param arr 待交换数组* @param startIndex 起始下标* @param endIndex 结束下标* @return left*/private static int partition(int[] arr, int startIndex, int endIndex) {//取第一个元素也可以随机取作为基准元素int pivot = arr[startIndex];int mark = startIndex;for (int i = startIndex+1; i < endIndex; i++) {if (arr[i]<pivot){mark ++;int temp = arr[mark];arr[mark] = arr[i];arr[i] = temp;}}//pivot和指针重复交换arr[startIndex] = arr[mark];arr[mark] = pivot;return mark;}public static void main(String[] args) {int[] arr = {4,7,2,5,6,1,8};quickSort(arr,0,arr.length-1);System.out.println(Arrays.toString(arr));}
快速排序原理解析(简单易懂图文代码配套)相关推荐
- Python 快速排序算法【简单易懂,代码直接运行】
Python 快速排序算法[简单易懂,代码直接运行] 给定你一个长度为 n 的整数数列. 请你使用快速排序对这个数列按照从小到大进行排序. 并将排好序的数列按顺序输出. 输入格式 输入共两行,第一行包 ...
- python 提取出所有学生的序号,姓名,成绩(简单易懂,代码可以直接运行,非正则表达式)
python 提取出所有学生的序号,姓名,成绩(简单易懂,代码可以直接运行,非正则表达式) 非正则表达式提取信息利用的是字符串的切片原理,商铺先用spilt函数将每一条<tr><\t ...
- ISO7816协议深度解析-简单易懂协议详解(一)-- 复位,字符帧,及ATR
1. 摘要 IC卡必须支持T=0或T=1的协议,但不是同时支持这两种协议,而终端则必须同时支持T=0和T=1的协议. • T=0通讯协议是异步半双工字符传输协议: • T=1通讯协议是异步半双工块传输 ...
- python 提取出所有学生的序号,姓名,成绩(简单易懂,代码可以直接运行)
python 提取出所有学生的序号,姓名,成绩(简单易懂,代码可以直接运行)(正则表达式提取) 数据如下: <tbody> <tr><td><span> ...
- C语言/C++ 矩阵的右下半部分【简单易懂,代码可以直接运行】
C语言/C++ 矩阵的右下半部分[简单易懂,代码可以直接运行] 输入一个二维数组 M[12][12],根据输入的要求,求出二维数组的右下半部分元素的平均值或元素的和. 右下半部分是指次对角线下方的部分 ...
- python矩阵的右下半部分【简单易懂,代码可以直接运行】
python矩阵的右下半部分[简单易懂,代码可以直接运行] 输入一个二维数组 M[12][12],根据输入的要求,求出二维数组的右下半部分元素的平均值或元素的和. 右下半部分是指次对角线下方的部分,如 ...
- JavaScript编写日历(简单易懂,代码可以直接运行)
JavaScript编写日历(简单易懂,代码可以直接运行) 运行效果图如下: 点个
- Python 一文学会字典数据类型【简单易懂,代码可以直接运行,强烈推荐】
Python 一文学会字典数据类型[简单易懂,代码可以直接运行,强烈推荐] ''' 字典的含义:字典存储的是生活中一个物体的信息 字典的特征: 组成它的数据:key:value组合 字典中的key不能 ...
- Python 字符串系列三字符串的拼接拆分和判断【简单易懂,代码可以直接运行,强烈推荐】
Python 字符串系列三字符串的拼接拆分和判断[简单易懂,代码可以直接运行,强烈推荐] ''' 字符串的拼接和拆分 #拆分和拼接 在''中\是转义字符,只有\才表示一个 ''' #以文件路径为例 p ...
最新文章
- C#命名规则、开发习惯和风格
- Android OTA在线升级二(升级包编译原理分析) 【转】
- spring security 允许 iframe 嵌套
- 如何设置input实现同时选中多个文件并同时上传
- 读《移山之道》的收获与疑问(阅读作业之刘明篇)
- Windows XP Embedded with Service Pack 2 开发包光盘 3CD
- 关于php车服务论文,「PHP」行车服务app后端代码简析
- Learning Data Structure_2_线性表、栈和队列
- 坑nyoj1088 just do it
- 商城口碑高的蓝牙耳机好用吗?十大高人气蓝牙耳机测评推荐
- 学校计算机课怎取消红蜘蛛,谁知道怎么退出或卸载“红蜘蛛教学系统” 各位高手帮帮忙啊。。。(我们老师一讲就是一节课)...
- Tom的页面专题制作工具Pagemaker化腐朽为神奇
- Tuxera NTFS2023Mac读写ntfs磁盘工具
- python主成分分析_Python主成分分析-经典案例分析
- 性能测试理论(一)之性能测试方法与流程
- 用Python写随机密码生成
- 什么是范式?第一范式、第二范式、第三范式的区别?
- 附代码 ExFuse
- Labelme左边的工具栏没有了?
- 马化腾:视频号基本是全公司的希望;雷军宣布小米人事调整:总裁王翔月底退休,卢伟冰晋升接任;QT 6.5 Beta发布|极客头条
热门文章
- 使用.Net5尝鲜的一些小总结及Configuration.Json读取配置文件的使用
- python 能源系统建模:message-ix Integrated assessment model的安装
- 【服务器数据恢复】Raid阵列更换故障硬盘后数据同步失败的数据恢复案例
- 从微信云托管容器镜像的选择-alpine 说起
- 合江长江公路大桥飞燕式系杆拱桥首节主拱成功吊装
- linux ipxe 自动windows,PXE批量部署Linux五:使用iPXE代替PXELINUX
- ipxe下使用pxe的启动方式
- 音频2-ALSA/ASOC音频驱动框架
- Conv2d和Conv3d详解
- 8.跨阻放大器TIA的阻抗:无穷大还是零? 究竟是什么?