快速排序(单边、双边两种)

2024-04-06 04:04

本文主要是介绍快速排序(单边、双边两种),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

无论是单边快排还是双边快排都需要注意以下一些关键点:

1.快排核心在于递归。

2.每回都需要选择一个基准元素,将该基准元素放置正确位置,并且将比其小的元素统统移到该位置左边,比其大的元素移到该元素右边。

3.防置完毕后需要拿到基准元素的位置,再分别对左右两边调用该方法进行递归。

双边快排:

1.1.需要注意边界问题,两个指针移动时也要判断i<j。

1.2.需要注意最后ij重合的位置,需要考虑这个位置和基准元素的大小关系,因为都有可能。

package mainimport "fmt"// 双边快排
func quickSort(arr []int, left int, right int) {if left < right {pos := partition(arr, left, right)quickSort(arr, left, pos-1)quickSort(arr, pos+1, right)}
}func partition(arr []int, left int, right int) int {i := leftj := rightpivot := arr[left]for i < j {for i < j && arr[i] <= pivot {i++}for i < j && arr[j] > pivot {j--}//i==j,或者真的需要交换,交换即可swap(arr, i, j)}pos := iif arr[pos] > pivot {pos--swap(arr, left, pos)} else {swap(arr, left, pos)}return pos
}func swap(arr []int, i int, j int) {if i != j {temp := arr[i]arr[i] = arr[j]arr[j] = temp}
}//func main() {
//	arr := make([]int, 5)
//	arr[0] = 2
//	arr[1] = 1
//	arr[2] = 4
//	arr[3] = 3
//	arr[4] = 5
//	fmt.Println(arr)
//	quickSort(arr, 0, len(arr)-1)
//	fmt.Println(arr)
//}func main() {arr := make([]int, 8)arr[0] = 2arr[1] = 3arr[2] = 1arr[3] = 4arr[4] = 9arr[5] = 8arr[6] = 7arr[7] = 5fmt.Println(arr)quickSort(arr, 0, len(arr)-1)fmt.Println(arr)
}

单边快排:

2.1.需要额外注意,基准元素只能先选最后一个位置,因为在遍历过程中,第一个元素(位置较小的元素)有可能与其他比基准元素小的元素发生交换,最后想把基准元素放到应该的位置上时,却发现基准元素被换到未知地方去了

2.2.基准元素自身位置不需遍历 ,最后pointer指向的位置一定是大于基准元素的(如果有的话,否则是基准元素自身),因为比基准元素小的都移动到比pointer低的位置了,交换即可。没有的话pointer也会指向基准元素自身,交换与否无影响。

package mainimport ("fmt"
)// 单边快排
func quickSort(arr []int, low int, high int) {if low < high {pos := partition(arr, low, high)quickSort(arr, low, pos-1)quickSort(arr, pos+1, high)}
}// 返回基准元素的position,并将基准元素放在正确位置
func partition(arr []int, low int, high int) int {//基准元素取最高,防止基准元素交换位置被交换的未知位置pivot := arr[high]pointer := low//<high,high不用遍历for i := low; i < high; i++ {if arr[i] <= pivot {//swaptemp := arr[i]arr[i] = arr[pointer]arr[pointer] = temp//指针后移pointer++}}//基准元素一到正确位置上temp := arr[pointer]arr[pointer] = arr[high]arr[high] = tempreturn pointer
}func main() {arr := make([]int, 5)arr[0] = 2arr[1] = 1arr[2] = 4arr[3] = 3arr[4] = 5fmt.Println(arr)quickSort(arr, 0, len(arr)-1)fmt.Println(arr)
}

这篇关于快速排序(单边、双边两种)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/878955

相关文章

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

springboot security快速使用示例详解

《springbootsecurity快速使用示例详解》:本文主要介绍springbootsecurity快速使用示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录创www.chinasem.cn建spring boot项目生成脚手架配置依赖接口示例代码项目结构启用s

Docker镜像pull失败两种解决办法小结

《Docker镜像pull失败两种解决办法小结》有时候我们在拉取Docker镜像的过程中会遇到一些问题,:本文主要介绍Docker镜像pull失败两种解决办法的相关资料,文中通过代码介绍的非常详细... 目录docker 镜像 pull 失败解决办法1DrQwWCocker 镜像 pull 失败解决方法2总

在C#中调用Python代码的两种实现方式

《在C#中调用Python代码的两种实现方式》:本文主要介绍在C#中调用Python代码的两种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#调用python代码的方式1. 使用 Python.NET2. 使用外部进程调用 Python 脚本总结C#调

IDEA中Git版本回退的两种实现方案

《IDEA中Git版本回退的两种实现方案》作为开发者,代码版本回退是日常高频操作,IntelliJIDEA集成了强大的Git工具链,但面对reset和revert两种核心回退方案,许多开发者仍存在选择... 目录一、版本回退前置知识二、Reset方案:整体改写历史1、IDEA图形化操作(推荐)1.1、查看提

Android自定义Scrollbar的两种实现方式

《Android自定义Scrollbar的两种实现方式》本文介绍两种实现自定义滚动条的方法,分别通过ItemDecoration方案和独立View方案实现滚动条定制化,文章通过代码示例讲解的非常详细,... 目录方案一:ItemDecoration实现(推荐用于RecyclerView)实现原理完整代码实现

Redis解决缓存击穿问题的两种方法

《Redis解决缓存击穿问题的两种方法》缓存击穿问题也叫热点Key问题,就是⼀个被高并发访问并且缓存重建业务较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的冲击,本文给大家介绍了Re... 目录引言解决办法互斥锁(强一致,性能差)逻辑过期(高可用,性能优)设计逻辑过期时间引言缓存击穿:给

C++快速排序超详细讲解

《C++快速排序超详细讲解》快速排序是一种高效的排序算法,通过分治法将数组划分为两部分,递归排序,直到整个数组有序,通过代码解析和示例,详细解释了快速排序的工作原理和实现过程,需要的朋友可以参考下... 目录一、快速排序原理二、快速排序标准代码三、代码解析四、使用while循环的快速排序1.代码代码1.由快

VSCode中C/C++编码乱码问题的两种解决方法

《VSCode中C/C++编码乱码问题的两种解决方法》在中国地区,Windows系统中的cmd和PowerShell默认编码是GBK,但VSCode默认使用UTF-8编码,这种编码不一致会导致在VSC... 目录问题方法一:通过 Code Runner 插件调整编码配置步骤方法二:在 PowerShell

Win32下C++实现快速获取硬盘分区信息

《Win32下C++实现快速获取硬盘分区信息》这篇文章主要为大家详细介绍了Win32下C++如何实现快速获取硬盘分区信息,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 实现代码CDiskDriveUtils.h#pragma once #include <wtypesbase