深入理解快速排序算法

介绍

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

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

相关推荐
2401_841495642 小时前
【计算机视觉】基于复杂环境下的车牌识别
人工智能·python·算法·计算机视觉·去噪·车牌识别·字符识别
Jonkin-Ma2 小时前
每日算法(1)之单链表
算法
晚风残3 小时前
【C++ Primer】第六章:函数
开发语言·c++·算法·c++ primer
杨云强3 小时前
离散积分,相同表达式数组和公式
算法
地平线开发者3 小时前
征程 6 | BPU trace 简介与实操
算法·自动驾驶
满天星83035773 小时前
【C++】AVL树的模拟实现
开发语言·c++·算法·stl
Lris-KK3 小时前
力扣Hot100--94.二叉树的中序遍历、144.二叉树的前序遍历、145.二叉树的后序遍历
python·算法·leetcode
麦麦鸡腿堡4 小时前
Java的动态绑定机制(重要)
java·开发语言·算法
zy_destiny4 小时前
【工业场景】用YOLOv8实现抽烟识别
人工智能·python·算法·yolo·机器学习·计算机视觉·目标跟踪
坚持编程的菜鸟4 小时前
LeetCode每日一题——螺旋矩阵
c语言·算法·leetcode·矩阵