IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 快速排序算法 -> 正文阅读

[数据结构与算法]快速排序算法

快速排序算法介绍

快速排序是经常用到的一种排序方法,和冒泡排序不同的是,通过随机选择一个数作为基准pivot,通过比较,将数组划分为小于基准和大于基准的两部分。之后在分别对小于基准和大于基准的部分重复以上过程。通过递归实现整个数组的排序。

具体步骤

为了保证排序的效率,应该随机选取数组中的某个数作为基准。

  1. 随机选择[l, r]之间的一个基准pivot后,将所选数组与最后一位互换——将基准换至最后一位的目的是为了不影响前面比较的过程。
  2. 使用两个指针(在python中即为两个变化的索引值)i,j——其中i 表示当前小于基准部分的最大索引,初始值为l-1。此处 i=l-1 的原因是一开始默认第一位不是小于基准的数;j负责从l->r逐个遍历数组
  3. 分别比较 nums[j] 和 nums[r](此处是与nums[r]相比较,不再是nums[pivot],因为基准已经被换至最后),如果nums[j]<nums[r],说明当前的数小于基准,需要将i后移一位,并与当前的nums[j]互换。反之,则继续移动j
  4. 然后,将最后一位的基准换至小于基准部分的后面。此处需要先i++,因为基准是换至小于基准部分的后面。最后返回的也是i,所以需要操作i的值,而不是仅仅完成互换。

代码示例

class Solution():
	def partition(self, nums, l, r):
		p = random.randint(l, r)
		nums[p], nums[r] = nums[r], nums[p]
		i = l-1
		for j in range(l, r):
			if nums[j] < nums[r]:
				i += 1
				nums[j], nums[i] = nums[i], nums[j]
		i+=1
		nums[r], nums[i] = nums[i], nums[r]
		return i
	
	def quicksort(self, nums, l, r):
		if r-l<=0:
			return
		m = self.partition(nums, l, r)
		self.quicksort(nums, l, m-1)
		self.quicksort(nums, m+1, r)
		# 此处将nums[m]略过是因为m与前后已经有了明确的大小关系,无需再参与比较。
	def sort(self, nums):
		self.quicksort(nums, 0, len(nums)-1)
		return nums


if __name__ == "__main__":
	nums = [2,8,4,1,3,5,6,7]
	s = Solution()
	print(s.sort(nums))

直观

假设随机选取pivot=2
nums=[2,8,4,1,3,5,6,7]——>nums=[2,8,7,1,3,5,6,4]

jnums[j]inums[]<->nums[]
02-1+10<->0
18
27
310+1=13<->1 nums=[2,1,7,8,3,5,6,4]
431+1=24<->2 numd=[2,1,3,8,7,5,6,4]
55
66

最后将基准换至i后面——> nums=[2,1,3,4,7,5,6,8]

思考的几个问题

  1. j 遍历的 range(l, r)是从l->r,而不是r-1:因为在调用sort()时,传入的r已经是len(nums)-1,已经是数组最后一个的下表,也就是range(l, r)产生的最后一个j=r-1,刚好是基准的前一个数,故不需要r-1,否则会out of index
  2. nums[j]应该与nums[r]相比较:因为nums[pivot]已换至最后一位
  3. 为什么一开始i=l-1?因为尚不知道数组的第一个数与基准的关系,如果第一个数比基准大的话,此时i的索引已经为0,后续再次进入循环时,r+1=1,就直接跳过第一个数进行交换了。
  4. 最后基准换至i后时,为什么是先i+=1,而不是直接与nums[i+1]进行交换即可:因为最后需要返回基准所在的位置
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-07-29 11:53:53  更:2021-07-29 11:57:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/5 14:36:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码