文章主要针对自己在理解快速排序过程中当时卡壳的点,记录了接触这个算法的经历,不是对快速排序算法原理的分析和理解。

两种思维

我在网上找到了两种理解快速排序比较好的思维方法,具体的思路写在了注释中:

方法一:

 private static void quickSort1(int[] nums, int start, int end) {//递归出口,千万别忘了,当start==end的时候,代表只剩一个元素了,不需要再进行排序if (start >= end) {return;}//基准int point = nums[start];int i = start;int j = end;int t;while (i < j) {//从右向左进行扫描,找到第一个小于基准的值的位置,//之所以先从右向左进行,是为了后面swap处作铺垫while (nums[j] >= point && i < j) {j--;}//从左向右进行扫描,找到第一个大于基准的值的位置while (nums[i] <= point && i < j) {i++;}//如果 i<j 那么就进行交换,i<j 说明左边还是可能存在大于基准的值,还需要继续扫描,//直到 i==j 的时候说明已经满足“左边的值都小于基准,右边的值都大于等于基准”的约定,// i==j 的时候就会跳出外层的while循环,进入swapif (i < j) {t = nums[i];nums[i] = nums[j];nums[j] = t;}}//---------------------------swap--------------------------//这里会将 j 和基准进行交换,这里就能看出上面描述的先从右到左进行扫描的目的,// j 恰好小于基准,所以与基准交换后刚好满足“左边的值都小于基准,右边的值都大于等于基准”的约定nums[start]=nums[j];nums[j]=point;//---------------------------------------------------------System.out.println("Sorting: " + Arrays.toString(nums));quickSort1(nums, start, j - 1);quickSort1(nums, j + 1, end);
}

参照文章:【坐在马桶上看算法】算法3:最常用的排序——快速排序


方法二:

private static void quickSort2(int[] arr, int low, int high) {if (arr.length <= 0) return;if (low >= high) return;int left = low;int right = high;//挖坑1:保存基准的值int temp = arr[left];   while (left < right) {while (left < right && arr[right] >= temp) {  right--;}//挖坑2:从后向前找到比基准小的元素//填坑1:插入到基准位置坑1中arr[left] = arr[right];while (left < right && arr[left] <= temp) {   left++;}//挖坑3:从前往后找到比基准大的元素//填坑2:放到刚才挖的坑2中arr[right] = arr[left];}//填坑3:基准值填补到坑3中,准备分治递归快排arr[left] = temp;   System.out.println("Sorting: " + Arrays.toString(arr));quickSort2(arr, low, left - 1);quickSort2(arr, left + 1, high);
}

参照文章:八大排序算法总结与java实现


总结

  • 对于我来说,方法一是一个交换过程,而方法二是一个挖坑填坑的过程。之所以会产生这两种感觉的原因,我觉得是他们的值交换触发的时间点不同导致的。方法一是统一进行标记,标记结束后再一次性的进行交换;而方法二是在每次扫描之后就会进行交换。
  • 这里有一个点,我之前一直把扫描的范围设在start+1和end之间,把基准给排除出去了,而且一直以为很合理,但是使用{3, 3, 3, 3, 1, 6, 5}用例进行测试时总是出错,通过断点分析发现,如果扫描的数组恰好已经是有序的了,比如{1,2,3,4,5,6},那么在从后向前扫描的时候,j 的位置会停在start+1的位置上,即 j=i 的位置上,此时跳出外层的while循环,基准位和 j 位置的值进行交换,这样显然不合理,因为start的值根本没和start+1(也即是 j 最终的位置)进行过比较(这里j的while循环跳出是因为不满足了i<j的条件,而不是因为不满足nums[j]>=point),就进行了交换,这样的结果就是原来明明已经有序的数组又变成无序的了。

参考资料:

  • 【坐在马桶上看算法】算法3:最常用的排序——快速排序(这个图非常易懂,讲解由浅入深)
  • 八大排序算法总结与java实现(这个博客非常好,无论是美感还是内容设计)

算法和数据结构--快速排序相关推荐

  1. python算法与数据结构-快速排序算法(36)

    阅读目录 一.快速排序的介绍 二.快速排序的原理 三.快速排序的步骤 四.快速排序的图解 五.快速排序的python代码实现 六.快速排序的C言语代码实现 七.快速排序的时间复杂度 八.快速排序的稳定 ...

  2. python算法与数据结构-快速排序算法

    设定一个中间值,如下所示: low从开始位置找low是找比54小的,26比54小合格  high是从末尾位置找比54大的,如下所示: low和high重合后第一轮循环结束 第一轮递归后的结果如下所示: ...

  3. Caché 算法与数据结构

    第一章 Caché 算法与数据结构 基础和概念 ☆☆☆☆☆ 第二章 Caché 算法与数据结构 数组原理 ☆☆☆☆☆ 第三章 Caché 算法与数据结构 链表原理 ☆☆☆☆☆ 第四章 Caché 算法 ...

  4. 数据结构与算法-day3-归并 快速排序

    我的理解 上一节的末尾我说了,冒泡 插入 选择这三种时间复杂度都是O(n2),只适用于小规模排序,那么,相对常用的适用于大规模的排序又是哪些呢? 归并排序和快速排序都用到了分治思想,且代码通过递归来解 ...

  5. 数据结构(七)高级排序算法——归并、快速排序

    一.归并排序 1.排序原理 归并排序算法是一种利用了分治算法思想实现的排序算法,这种排序算法是基于有序数组合并的归并排序算法的基本思想就是:判断一个待排序序列的长度,只要这个待排序序列的长度是超过1的 ...

  6. 维基百科上的算法和数据结构链接很强大

    突然发现维基百科上的算法和数据结构比百度百科强多啦,图文并茂. 其实这个网站不错:http://www.sorting-algorithms.com 冒泡排序: bubble冒泡的意思 http:// ...

  7. GitHub标星3w+的项目,全面了解算法和数据结构知识

    作者 | 程序员小吴 来源 | 五分钟学算法(ID: CXYxiaowu) 导语:今天分享一个开源项目,里面汇总了程序员技术面试时需要了解的算法和数据结构知识,并且还提供了相应的代码,目前 GitHu ...

  8. 浅谈算法和数据结构: 五 优先级队列与堆排序

    原文:浅谈算法和数据结构: 五 优先级队列与堆排序 在很多应用中,我们通常需要按照优先级情况对待处理对象进行处理,比如首先处理优先级最高的对象,然后处理次高的对象.最简单的一个例子就是,在手机上玩游戏 ...

  9. python数据结构推荐书-「算法与数据结构」从入门到进阶吐血整理推荐书单

    推荐一下「算法与数据结构」从入门到进阶的书单. 一.入门系列 这些书籍通过图片.打比方等通俗易懂的方法来讲述,让你能达到懂一些基础算法,线性表,堆栈,队列,树,图,DP算法,背包问题等,不要求会实现, ...

  10. 【算法与数据结构】堆排序是什么鬼?

    排序算法相必大家都见过很多种,例如快速排序.归并排序.冒泡排序等等.今天,我们就来简单讲讲堆排序. 在上一篇中,我们讲解了二叉堆,今天的堆排序算法主要就是依赖于二叉堆来完成的,不清楚二叉堆是什么鬼的, ...

最新文章

  1. RYU控制器的学习笔记(三) 利用观察者模式通知app处理报文
  2. pycharm安装包时各种报错,且pip无法安装
  3. Hive Join Strategies hive的连接策略
  4. 前端学习(3075):vue+element今日头条管理-反馈
  5. 做10多年测试的老何
  6. Maven学习(六)————企业Maven项目最佳实践
  7. spring boot java app_利用spring boot创建java app
  8. 漫谈边缘计算(二):各怀心事的玩家
  9. zypper 删除mysql_如何在 Linux 上安装/卸载一个文件中列出的软件包?
  10. vue ui框架_Vue移动端UI框架指南
  11. 03-17 APP自动遍历测试技术
  12. ubuntu下安装配置 JDK7
  13. Linux驱动开发|电容触摸屏
  14. 【OpenCV学习】(三)色彩及矩阵操作
  15. 矩阵相乘求导(转载)
  16. PMP VS MBA:为什么我劝你别浪费钱读MBA
  17. 使用记录6_发布微信小游戏
  18. UWB超宽带 DW1000 通道和带宽
  19. muduo源码分析2——Singleton分析
  20. 反余弦函数用途之一:关系距离计算

热门文章

  1. 【PMSM矢量控制系列】磁场定向控制(FOC)原理
  2. 【调剂】大连理工大学电子信息与电气工程学部2022年硕士研究生招生考试调剂缺额与报名通知...
  3. 流计算 Oceanus 操作效率提升指南(一)
  4. java随机yujie_从.Net到Java学习第十一篇——SpringBoot登录实现
  5. Shell 脚本(五) Shell 工具-cut、sedawk、、
  6. 数字图像与机器视觉基础补充(2)——图像处理和分割车牌
  7. TCP/IP网络江湖——物理层护江山:网络安全的铁壁防线(物理层下篇:物理层与网络安全)
  8. vue3+ts出现 --找不到模块“@/views/XXX.vue”或其相应的类型声明。
  9. python css和xpath_一文学会Python爬虫框架scrapy的XPath和CSS选择器语法与应用
  10. 三甲医院手术麻醉系统源码, C# .net 桌面软件 C/S版源码