深入理解快速排序算法

介绍

快速排序(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 时停止递归。

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

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

tips:

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

cpp 复制代码
sizeof(a)/sizeof(a[0])
证明:

left与right相遇有两种情况:

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

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

扩展问题

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

答:若必须默认key为numright,应使left每次先走

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

总结

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

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

相关推荐
Code_Solitude6 小时前
C语言动态内存 + 柔性数组 + 数组名退化
c语言·算法·柔性数组
上海潭龙东海科技有限公司6 小时前
客运站管控之动态孪生技术方案(新增一屏管控模块
数据仓库·人工智能·算法·重构·动态规划
YLCHUP9 小时前
【思维&图论建模】题解:债权(debt)_图论_建模_思路转化_思维题目_C++算法竞赛
c++·笔记·算法·数学建模·贪心算法·深度优先·图论
思麟呀9 小时前
背包DP(01背包+完全背包)
c++·算法
笑容掩饰我的失落10 小时前
区块链从小白到精通(七):Solidity 语法精讲——数据类型、函数、修饰器与事件
算法·区块链·php·智能合约·哈希算法
Pniubi11 小时前
力扣24. 两两交换链表中的节点(递归)
算法·leetcode·链表
nice_lcj52011 小时前
LRU 缓存入门:它是什么、怎么用、面试怎么手写
java·数据结构·缓存·面试·lru
꧁细听勿语情꧂12 小时前
直接选择排序,堆排序,冒泡排序,递归快速排序、hoare版本、挖坑法、lomuto前后指针,非递归快速排序
c语言·开发语言·数据结构·算法
俊俊几年的13 小时前
动态规划(Dynamic Programming)详解:从入门到 LeetCode Hot 100
linux·c++·算法·leetcode·嵌入式·动态规划·c
小雉系统1 天前
BcoreOS安全通信架构:FsSession 抗算法后门安全设计
算法·安全·架构