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

2025-03-18 01:50
文章标签 c++ 讲解 快速 排序 详细

本文主要是介绍C++快速排序超详细讲解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

一、快速排序原理

快速排序(QuickjlrDBSort)是一种基于分治法的高效排序算法。它的基本思想是通过一个称为“基准”(pivot)的元素将数组划分为两部分,一部分的所有元素都比基准小,另一部分所有元素都比基准大,然后递归地对这两部分进行同样的操作,直到整个数组有序。 

二、快速排序标准代码

void quick_sort(int q[], int l, int r)
{
	if (l >= r) return; //递归停止条件
	int i = l - 1, j = r + 1, x = q[l + r >> 1]; //设定指针,基准
	while (i < j)
	{
		do i++; while (q[i] < x); //q[i]大于等于基准时,指针i停止
		do j--; while (q[j] > x); //q[j]小于等于基准时,指针j停止
		if (i < j) swap(q[i], q[j]); //判断是否i<j,交换i,j对应的数组元素
	} // 结束时数组被分为 >=x,<=x 的两部分
	quick_sort(q, l, j); //继jlrDB续分直到分到一到两个元素此时数组有序
	quick_sort(q, j + 1, r);
}

三、代码解析

我们以一个简单的例子帮助我们了解快速排序

53412

1.排序的数组以及需要排序元素的范围,无返回值

void quick_sort(int q[], int l, int r)

 2.递归结束的条件:元素剩一个或空

if (l >= r) return;

3.设定变量,其中 i, j 为两个指针分别减 1 加 1 是为了下一步的 do while 循环,x 即为“基准”(pivot) 用来将列表分为 <=x 和 >=x 的两部分,x 是随机的,这里取了数组中间的一个元素,l + r >> 1相当于 (l + r)/2 (pivot:q[2] = 4)向下取整(提高了效率)

int i = l - 1, j = r + 1, x = q[l + r >> 1];
53412
C++快速排序超详细讲解01234C++快速排序超详细讲解 j

4.while循环实现了遍历、比较、交换的功能,先使 i 指针递增直到 i 所对应的元素 >=x 停止,接下来使 j 指针递减直到其对应的元素 <=x 停止

while (i < j)
{
	do i++; while (q[i] < x);
	do j--; while (q[j] > x);
	if (i < j) swap(q[i], q[j]);
}
53412
i(>=4停止)j(<=4停止)

交换之后开启下一次循环

23415
<4<4i(>=4停止)j(<=4停止)>4

满足 i<j 交换

23145
<4<4j(<=4停止)i(>=4停止)

>4

不满足 i<j 不交换,此时整个 while 循环结束,注意此时 j(包含)往左为 <=4 部分,j + 1 及其往右为 >=4部分 

5.接下来就是递归了,每次运行分将数组为左<=右的两部分,我们只需将左右两部分分别执行函数程序得到直到剩两个或一个元素,此时数组便有序了

quick_sort(q, 0, 2); 
23145
<4<4j(<=4停止)i(>=4停止)

>4

x(pivot)=3

231
<3i(>=3停止)j(<=3停止)
213
<3j(<=3停止)i(>=3停止)
quick_sort(q, 0, 1); 

x(pivot)=2

2

1
i(>=2停止)j(<=2停止)

1

2
j(<=2停止)i(>=2停止)

剩一个元素时,执行递归停止程序:

if (l >= r) return;

 数组中最初的“左”部分就变为

123

而最初的“右”部分:x(pivot)=4

45
i(>=4停止)j(<=4停止)>5
if (i < j) swap(q[i], q[j]);

不满足 if 条件jlrDB以及 while 条件,while 循环停止,依旧选择了 j 为分界点分到一个元素时结束递归

此时代码全部有序

12345
quick_sort(q, l, j); 
quick_sort(q, j + 1, r);

6.总结

快速排序利用两个指针对数组的元素进行比较交换进行部分排序,再利用递归整体排序

四、使用while循环的快速排序

1.代码

代码1.由快排代码等价转化而来

void quick_sort(int q[], int l, int r)
{
    if (l >= r) return;
    int i = l, j = r, x = q[l + r >> 1];
    while (i < j)
    {
        while (q[i] < x) i++;
        while (q[j] > x) j--;
        if (i < j)
        {
            swap(q[i], q[j]);
            if (i + 1 < j - 1)
            {
                i++;
                j--;
            }
            else
            {
                i++;
                j--;
                while (q[i] < x) i++;
                while (q[j] > x) j--;
                break;
            }
        }
    }
    quickjs_sort(q, l, j);
    quick_sort(q, j + 1, r);
}

代码2.效率提高版

void quick_sort(int q[], int l, int r) {
	if (l >= r) return;
	int x = q[l + r >> 1];
	int i = l, j = r;
	while (i <= j) { // 注意:这里应该是 i <China编程= j 而不是 i < j
		while (q[i] < x) i++;
		while (q[j] > x) j--;
		if (i <= j) {
			swap(q[i], q[j]);
			i++;
			j--;
		}
	}
	quick_sort(q, l, j);   
	quick_sort(q, i, r);   
}

2.代码2解析

1.因为没有 do 过程,所以指针起始位置直接设在了 0 和 -1 的位置,

if (l >= r) return;
int x = q[l + r >> 1];
int i = l, j = r;
53412
iC++快速排序超详细讲解C++快速排序超详细讲解j

2. while 循环中的 while 循环先判断是否满足条件,满足的话指针加/减 1,这样停止时依旧是对应元素 >=x 或 <=x 时的指针,

while (i <= j) 
{ 
	while (q[i] < x) i++;
	while (q[j] > x) j--;
	if (i <= j)
    {
		swap(q[i], q[j]);
		i++;
		j--;
	}
}
53412
i(停)j(停)

换过之后+=或--

23415
<4i(停)j(停)

交换,++/--

23145
ji

不满足 i<=j while 循环结束.

关于 i<=j 的条件判断,我们给出新的案例

321
i(停)j(停)

交换之后 ++/--

123
i(停) j(停)

注意此时并没有返回(return),

递归代码:分别以 j 和 i 作为分界点

quick_sort(q, l, j);   
quick_sort(q, i, r);   

而如果条件判断为 < 的话 i=j 时就会造成下一次递归多了一个元素,

而标准代码的运行过程到此处后结束,以 j 和 j+1 为分界点不会造成此问题.

因此再进行一次循环

123
ji

而此时元素 2 的位置是 i,j同时停过的位置即为基准 x,而i,j也会再下一次++/--后停止,所以我们可以直接将元素 2 所对应的数组位置固定不动,将元素 2 左右的数组递归处理. 

quick_sort(q, l, j);   
quick_sort(q, i, r);   

五、总结

使用 while 循环会比 do while 多一层内层循环,所以 do while 循环效率更高,建议只用 do while 循环.

到此这篇关于C++快速排序的文章就介绍到这了,更多相关C++快速排序内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于C++快速排序超详细讲解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

C#如何调用C++库

《C#如何调用C++库》:本文主要介绍C#如何调用C++库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录方法一:使用P/Invoke1. 导出C++函数2. 定义P/Invoke签名3. 调用C++函数方法二:使用C++/CLI作为桥接1. 创建C++/CL

IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤及问题解决

《IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决》:本文主要介绍IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决,本文分步骤结合实例给大... 目录步骤 1:创建 Maven Web 项目步骤 2:添加 Spring MVC 依赖1、保存后执行2、将新的依赖

快速修复一个Panic的Linux内核的技巧

《快速修复一个Panic的Linux内核的技巧》Linux系统中运行了不当的mkinitcpio操作导致内核文件不能正常工作,重启的时候,内核启动中止于Panic状态,该怎么解决这个问题呢?下面我们就... 感谢China编程(www.chinasem.cn)网友 鸢一雨音 的投稿写这篇文章是有原因的。为了配置完

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

如何为Yarn配置国内源的详细教程

《如何为Yarn配置国内源的详细教程》在使用Yarn进行项目开发时,由于网络原因,直接使用官方源可能会导致下载速度慢或连接失败,配置国内源可以显著提高包的下载速度和稳定性,本文将详细介绍如何为Yarn... 目录一、查询当前使用的镜像源二、设置国内源1. 设置为淘宝镜像源2. 设置为其他国内源三、还原为官方

最详细安装 PostgreSQL方法及常见问题解决

《最详细安装PostgreSQL方法及常见问题解决》:本文主要介绍最详细安装PostgreSQL方法及常见问题解决,介绍了在Windows系统上安装PostgreSQL及Linux系统上安装Po... 目录一、在 Windows 系统上安装 PostgreSQL1. 下载 PostgreSQL 安装包2.

Python利用ElementTree实现快速解析XML文件

《Python利用ElementTree实现快速解析XML文件》ElementTree是Python标准库的一部分,而且是Python标准库中用于解析和操作XML数据的模块,下面小编就来和大家详细讲讲... 目录一、XML文件解析到底有多重要二、ElementTree快速入门1. 加载XML的两种方式2.

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类

MySql match against工具详细用法

《MySqlmatchagainst工具详细用法》在MySQL中,MATCH……AGAINST是全文索引(Full-Textindex)的查询语法,它允许你对文本进行高效的全文搜素,支持自然语言搜... 目录一、全文索引的基本概念二、创建全文索引三、自然语言搜索四、布尔搜索五、相关性排序六、全文索引的限制七

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文