深入理解快速排序算法

介绍

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

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

原理概述

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

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

C 语言代码实现

cpp 复制代码
#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 时停止递归。

  • 每次移动 leftright 时保证 left < right,防止越界。

  • 选择基准元素可以是数组的第一个元素,也可以是最后一个元素,具体实现时要根据需求选择合适的基准元素。

tips:

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

cpp 复制代码
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),具有原地排序的特点。通过合理选择基准元素、优化算法细节,可以进一步提高排序效率。希望以上详细的解释能帮助你更好地理解快速排序算法的原理和执行过程。

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

相关推荐
自我意识的多元宇宙4 小时前
树与二叉树--二叉树的存储结构
数据结构
白羊by6 小时前
YOLOv1~v11 全版本核心演进总览
深度学习·算法·yolo
墨尘笔尖7 小时前
最大最小值降采样算法的优化
c++·算法
自我意识的多元宇宙8 小时前
二叉树的遍历和线索二叉树--二叉树的遍历
数据结构
qq_5024289909 小时前
清华大学与微软亚洲研究院出品:Kronos 本地部署教程
数据结构·python·金融量化·kronos开源模型
white-persist9 小时前
【vulhub shiro 漏洞复现】vulhub shiro CVE-2016-4437 Shiro反序列化漏洞复现详细分析解释
运维·服务器·网络·python·算法·安全·web安全
FL162386312910 小时前
基于C#winform部署软前景分割DAViD算法的onnx模型实现前景分割
开发语言·算法·c#
baizhigangqw10 小时前
启发式算法WebApp实验室:从搜索策略到群体智能的能力进阶
算法·启发式算法·web app
C雨后彩虹11 小时前
最多等和不相交连续子序列
java·数据结构·算法·华为·面试
cpp_250111 小时前
P2347 [NOIP 1996 提高组] 砝码称重
数据结构·c++·算法·题解·洛谷·noip·背包dp