算法随笔 — 排序算法 — 快速排序

本文详细介绍了快速排序的实现原理,包括普通快排、单边递归快排和分区快排,强调了基准值选择的重要性。同时,文章通过分析相关习题如LeetCode的排序数组、链表排序等问题,展示了快速排序的应用,并探讨了与其他排序算法结合的可能性,如插入排序。此外,还讨论了智力发散题,如盛最多水的容器和用rand7()实现rand10()的问题。
摘要由CSDN通过智能技术生成

快速排序实现原理

在不同的实现方法中,按照交换值的方法可以分为 赋值两数值交换,这个现在理解不了没关系,先带着这个观点继续往后看

普通快排

以升序为例,实现步骤如下图所示
快排1实现步骤
快排1原理

function quick_sort_v1(arr: number[], l: number, r: number) {
   
  if (l >= r) return
  let x = l, y = r, base = arr[l] // 选择操作区间第一位作为基准值
  while(x < y) {
   
    while(x < y && arr[y] > base) y--
    if (x < y) arr[x++] = arr[y]
	while(x < y && arr[x] <= base) x++
	if (x < y) arr[y--] = arr[x]
  }
  arr[x] = base
  // 此时数组已被基准值分为大小两部分,接着对其进行递归操作
  quick_sort_v1(arr, l, x - 1)
  quick_sort_v1(arr, x + 1, r)
}

单边递归快排

从上面的实现方法可以看到,每次操作需要进行两次递归操作,通过单边递归我们可以将递归操作减少至1次,从而减少空间的使用

单边递归原理

function quick_sort_v2(arr: number[], l: number, r: number) {
   
  let x: number, y: number, base: number
  while(l < r) {
   
	x = l
	y = r
	base = arr[l]
	while(x < y) {
   
	  while(x < y && arr[y] > base) y--
	  if (x < y) arr[x++] = arr[y]
	  while(x < y && arr[x] <= base) x++
	  if (x < y) arr[y--] = arr[x]
	}
	arr[x] = base
	quick_sort_v2(arr, x + 1, r)
	r = x - 1
  }
}

从以上代码可以看出,原来需要的两次递归操作现在只要一次就可以了

总结一下,以上两种方法,在交换值时是直接赋值的,这意味着在程序运行时,数组是缺了一个元素的,这就意味着阈值(或者说基准值)不能随便选,只能取操作区间的头部或者尾部

以上两段代码的基准值选择都是选择了操作空间的第一个

如果随机选阈值,最后极可能会出现“吞数字”的情况,如下图所示
吞数字

分区快排

分区快排结合了快排和插入排序的优点

从上面介绍的两种快排方法来看,最终运行的效率取决于中间值选得好不好(看脸)
快 排 时 间 复 杂 度 = { O ( n l o g n ) 一般 O ( l o g n ) 理想 O ( n 2 ) 最差 快排时间复杂度=\begin{cases}O(nlogn) & \text{一般} \\ O(logn) & \text{理想}\\ O(n^2) & \text{最差} \end{cases} =O(nlogn)O(logn)O(n2)一般理想最差
而插入排序的时间复杂度如下
插 入 排 序 时 间 复 杂 度 = { O ( n 2 ) 一般 O ( n ) 相对有序 插入排序时间复杂度=\begin{cases} O(n^2) & \text{一般} \\ O(n) & \text{相对有序} \end{cases} ={ O(n2)O(n)一般相对有序

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值