深入理解快速排序算法

介绍

快速排序(Quick Sort)是一种极其重要且有实际意义的经典算法,广泛应用于各种排序函数,由其名称也可知道其主要特点:快速

快速排序通过递归地将数组分割成较小的子集并对子集进行排序来实现。其核心思想是选取一个基准元素,将小于基准的元素移到基准的左边,大于基准的元素移到右边,再递归地对左右子数组进行同样的操作,最终完成整个数组的排序。

原理概述

快速排序的核心在于每一轮排序后,基准元素都位于它最终应该处于的位置上。具体来说,每单次排序都是通过移动指针,使得一个元素到达正确的位置,并且保证左边的元素都小于它,右边的元素都大于它。

当对每个元素都进行一轮上述排序后,每个元素都会到达正确位置,序列本身也就变成有序的了

C 语言代码实现

#include <stdio.h>
//交换函数
void swap(int* a, int* b)
{int tmp = *a;*a = *b;*b = tmp;
}void Print(int* a, int k)
{int i = 0;
//	printf("sizeof(a) = %d, sizeof(a[0]) = %d\n)", sizeof(a), sizeof(a[0]));
//	printf("size=%d\n", sizeof(a)/sizeof(a[0]));for (i = 0; i < k; i++){printf("%d ", a[i]);}printf("\n");
}void QuickSort(int* a, int left, int right)
{//begin和end保留初始left和right值int begin = left, end = right;int key = left;//终止条件:if (left>=right){return;}while(left<right){//每次left或right移动时保证left<right, 防止越界while(left<right && a[right]>=a[key]){right--;}while(left<right && a[left]<=a[key]){left++;}swap(&a[left], &a[right]);}swap(&a[left], &a[key]);QuickSort(a, begin, left-1);QuickSort(a, left+1, end);
}int main()
{int a[10]={6, 1, 2, 7, 9, 3, 4, 5, 10, 8};QuickSort(a, 0, 9);Print(a, sizeof(a)/sizeof(a[0]));return 0;
} 

注意点

  • 每次都要right先走,保证相遇时所指元素比key小,(证明见后)

  • 分治终止条件:low < high 时停止递归。
  • 每次移动 left 或 right 时保证 left < right,防止越界。
  • 选择基准元素可以是数组的第一个元素,也可以是最后一个元素,具体实现时要根据需求选择合适的基准元素。
tips:

在Print函数中,我原来想用下列语句代替参数k来表示数组a元素个数, 但发现此方法行不通,应为当数组指针作为参数传到其他函数中后,再次函数中,该指针只代表普通指针,sizeof会识别为数组指针,所以sizeof(a)的值恒为4或8,sizeof(a)/sizeof(a[0])值恒为1或2,也就不能表示数组大小了

sizeof(a)/sizeof(a[0])
证明:

left与right相遇有两种情况:

L走向R时相遇:相遇处的R肯定是比key小才能使R停下来

R走向L时相遇:此时L还没动,L处肯定时小于key

扩展问题

如果要求每次key必须选为a[right],原程序该如何调整呢?

答:若必须默认key为num[right],应使left每次先走

证明方法同上,建议读者自己动脑证明练习

总结

快速排序是一种高效的排序算法,平均时间复杂度为 O(nlogn),具有原地排序的特点。通过合理选择基准元素、优化算法细节,可以进一步提高排序效率。希望以上详细的解释能帮助你更好地理解快速排序算法的原理和执行过程。

最后真心希望我的博客能对你有所帮助,感谢阅读!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/759481.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker 哲学 - ip 的组成规则 与 网关介绍

在 IP 地址中&#xff0c;我们通常将 IP 地址分为两部分&#xff1a;网络部分和主机部分。网络部分用于标识网络&#xff0c;主机部分用于标识该网络中的特定主机。 IP 地址的每个部分&#xff08;也被称为一个八位组或一个字节&#xff09;可以是从0到255的任何值。 一个 IPv4…

[隐私计算实训营学习笔记] 第1讲 数据要素流通

信任四基石 数据的分级分类 技术信任&#xff1a;全链路审计、闭环完成的数据可信流通体系 技术信任&#xff1a;开启数据密态时代 数据可流通的基础设施&#xff1a;密态天空计算

LeetCode 面试经典150题 罗马数字转整数

题目&#xff1a; 罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M …

ZnO非线性电阻片功率损耗的频率特性

对不同频率正弦交流电压作用下直流氧化锌阀片的功率损耗进行了测量。图3.16(a)和(b)分别为试品类型A和试品类型B两种直流ZnO阀片在不同频率电压作用下的功率损耗随荷电率变化的特性。两种阀片的功率损耗都随频率和荷电率的增加而增加。当频率达到1kHz或以上时,阀片的功率损耗增…

Django项目不显示图片,路径找不到

1.问题 创建Django项目简单写一个网页&#xff0c;文字能显示&#xff0c;图片却无法加载&#xff0c;路径错误&#xff0c;找不到图片。 2.背景 我的项目结构 C:. ├─.idea │ └─inspectionProfiles ├─app01 │ ├─migrations │ ├─templates │ │ ├─app0…

JVM垃圾收集器你会选择吗?

目录 一、Serial收集器 二、ParNew收集器 三、Paralle Scavenge 四、Serial Old 五、Parallel Old 六、CMS收集器 6.1 CMS对处理器资源非常敏感 6.2 CMS容易出现浮动垃圾 6.3 产生内存碎片 七、G1 收集器 八、如何选择合适的垃圾收集器 JVM 垃圾收集器是Java虚…

玩转C语言——C语言中内存存储

一、 整数在内存中的存储 我们知道&#xff1a;整数的2进制表⽰⽅法有三种&#xff0c;即 原码、反码和补码 三种表⽰⽅法均有符号位和数值位两部分&#xff0c;符号位都是⽤0表⽰“正”&#xff0c;⽤1表⽰“负”&#xff0c;⽽数值位最 ⾼位的⼀位是被当做符号位&#xff0c;…

【K8s】Kubernetes网络完全指南和CNI讲解

【K8s】Kubernetes网络完全指南和CNI讲解 目录 【K8s】Kubernetes网络完全指南和CNI讲解Kubernetes网络模型Kubernetes网络实现Kubernetes服务Kubernetes DNS出站NAT双栈CNI使用 Kubernetes 部署 CNI 的方法推荐超级课程: Docker快速入门到精通Kubernetes入门到大师通关课

【Java】使用 Java 语言实现一个冒泡排序

大家好&#xff0c;我是全栈小5&#xff0c;欢迎阅读小5的系列文章。 这是《Java》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识…

【动态三维重建】Deformable 3D Gaussians 可变形3D GS用于单目动态场景重建(CVPR 2024)

主页&#xff1a;https://ingra14m.github.io/Deformable-Gaussians/ 代码&#xff1a;https://github.com/ingra14m/Deformable-3D-Gaussians 论文&#xff1a;https://arxiv.org/abs/2309.13101 文章目录 摘要一、前言二、相关工作2.1 动态场景的神经渲染2.2 神经渲染加速 三…

【Web应用技术基础】HTML(3)——表格

目录 题目1&#xff1a;原始表格 题目2&#xff1a;width、height 题目3&#xff1a; cellpadding 题目4&#xff1a;cellspacing、cellpadding 题目5&#xff1a;caption 题目6&#xff1a;rowspan 题目7&#xff1a;colspan 题目8&#xff1a;汇总题 题目1&#xff1…

从零到一构建短链接系统(八)

1.git上传远程仓库&#xff08;现在才想起来&#xff09; git init git add . git commit -m "first commit" git remote add origin OLiyscxm/shortlink git push -u origin "master" 2.开发全局异常拦截器之后就可以简化UserController 拦截器可以…

彻底讲透:如何写sql能够有效的使用到复合索引?

在MySQL中&#xff0c;有效的使用复合索引需要确保查询条件按照索引定义的列顺序进行。以下是一个具体的例子&#xff1a; 假设我们有一个sales表&#xff0c;它有四个字段&#xff1a;customer_id、product_category、sale_date和amount。为了优化包含这些字段查询的性能&…

Maxwell监听mysql的binlog日志变化写入kafka消费者

一. 环境&#xff1a; maxwell:v1.29.2 (从1.30开始maxwell停止了对java8的使用&#xff0c;改为为11) maxwell1.29.2这个版本对mysql8.0以后的缺少utf8mb3字符的解码问题&#xff0c;需要对原码中加上一个部分内容 &#xff1a;具体也给大家做了总结 &#xff1a; 关于v1.…

【Godot4.2】随机数入门指南

概述 计算机程序是精确的艺术&#xff0c;现实生活却充满了随机性。如果你的游戏缺乏了随机性&#xff0c;也就缺乏了最基础的乐趣。 我们在很多场景下需要使用随机数&#xff0c;来为已经非常刻意和规整的设计带来一些变化和趣味。 比如打怪、打完Boss或开宝箱后随机掉落不…

在MongoDB建模1对N关系的基本方法

“我在 SQL 和规范化数据库方面拥有丰富的经验&#xff0c;但我只是 MongoDB 的初学者。如何建立一对 N 关系模型&#xff1f;” 这是我从参加 MongoDB 分享日活动的用户那里得到的最常见问题之一。 我对这个问题没有简短的答案&#xff0c;因为方法不只有一种&#xff0c;还有…

软件系统开发设计的基本流程

一、前言 经过年的工程实践软件系统开发的流程演变有很多种&#xff0c;但是最基本的还是瀑布模型。但是由于近几年演变了很多种模型&#xff0c;现在很多公司的研发流程并不遵循瀑布模型。主要原因是无法满足市场竞争的需求。比如在哪某个节日需要敏捷上线活动等这样的场景。没…

ASP .Net Core 配置集合 IConfiguration 的使用

&#x1f433;简介 IConfiguration 是 ASP.NET Core 中的一个接口&#xff0c;用于表示配置集合。以下是关于 IConfiguration 的详细介绍&#xff1a; 作用&#xff1a;IConfiguration 允许开发人员从各种来源&#xff08;如文件、环境变量、命令行参数等&#xff09;读取应用…

ASP.NET中的GridView和DataList控件:功能、应用与比较

目录 一、引言 二、GridView控件 三、DataList控件 四、GridView与DataList的比较 五、结论 一、引言 ASP.NET是微软公司开发的一款强大的Web应用程序开发框架&#xff0c;它提供了丰富的控件库&#xff0c;使得开发人员能够更快速、更高效地构建功能强大的Web应用程序。…

【工具类】vscode 常用功能

1. vscode 常用功能 1. vscode 常用功能 1.1. 关闭右侧预览功能1.2. 快捷键(右键或者菜单栏多看看就记住了)1.3. 常用插件 1.1. 关闭右侧预览功能 点击文件-首选项-设置,搜索 “editor.minimap.enabled” ,默认值为打钩,我们只需要把钩去掉即可&#xff1b; 1.2. 快捷键(右…