15.快速排序

本文详细介绍了快速排序算法,强调其非稳定性特点,并通过具体代码实现了快速排序过程。重点讲解了partition函数,该函数常被独立应用于寻找最大或最小元素等场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

快速排序是所有面试中手写代码问题中频率最高的,没有之一

需要写的很熟练,值得注意的是快速排序并不是稳定的

partition函数是重点,有的时候会拿出来单独使用,比如求最大的几个数

下面是代码

#include <iostream>
using namespace std;
int a[] = { 5,13,6,24,2,8,19,27,6,12,1,17 };
void swap(int &s,int &r)
{
	int t = r;
	r = s;
	s = t;
}

int partition(int s, int r)
{
	int p = s;
	int q = r+1;			//这个+1很关键,因为后面的--q
	int key = a[p];
	
	while (1)
	{
		while (a[++p] < key && p < q);	//从头查找第一个大于key的数
		while (a[--q] > key);			//从尾查找第一个小于key的数
		if (p >= q)						//如果尾指针小于头指针,结束
			break;
		swap(a[p],a[q]);				
	}
	swap(a[s],a[q]);					//把key放到分界点
	return q;
}

void quicksort(int s,int r)
{
	if (s < r)
	{
		int t = partition(s,r);
		quicksort(s,t-1);
		quicksort(t + 1, r);
	}
}

void main()
{
	int s=0, r=11;
	quicksort(s, r);
}


### 快速排序算法的实现与原理 快速排序(Quick Sort)是一种基于治法的高效排序算法,最初由 Tony Hoare 于 1960 年提出[^1]。该算法的核心思想是通过选择一个“基准”元素(Pivot),将待排序的数据划为两部:一部小于等于基准值,另一部大于基准值;随后递归地对这两部数据进行相同的划操作,直到整个序列变为有序。 #### 原理概述 快速排序的主要步骤如下: 1. **选择基准值**:从数组中挑选一个元素作为基准值(通常是第一个元素、最后一个元素或者随机选取的一个元素)。 2. **区操作**:重新排列数组中的元素,使得所有小于基准值的元素位于左侧,而所有大于基准值的元素位于右侧。这一过程称为区(Partitioning)。 3. **递归排序**:别对基准值两侧的子数组重复上述过程,直至子数组长度为零或一为止。 最终的结果是一个完全有序的数组[^4]。 #### 时间复杂度析 - 最好情况下的时间复杂度为 \(O(n \log n)\),此时每次区都能均匀割数组。 - 最坏情况下时间复杂度为 \(O(n^2)\),这种情况发生在每次区都极不均衡的情况下,例如已经接近有序的数组。 - 平均时间复杂度为 \(O(n \log n)\)[^2]。 #### 空间复杂度 由于快速排序采用了递归的方式实现,因此空间复杂度主要取决于递归栈的深度。最好情况下递归栈深度为 \(O(\log n)\),而在最坏情况下可能达到 \(O(n)\)[^2]。 --- ### C++ 实现代码示例 以下是快速排序的一种典型实现方式: ```cpp #include <iostream> using namespace std; // 区函数 int partition(int arr[], int low, int high) { int pivot = arr[high]; // 选择最后一个元素作为基准值 int i = (low - 1); // 小于基准值的部索引初始化 for (int j = low; j <= high - 1; j++) { if (arr[j] < pivot) { // 如果当前元素小于基准值 i++; // 更新小于基准值区域的边界 swap(arr[i], arr[j]); // 交换位置 } } swap(arr[i + 1], arr[high]); // 将基准值放到正确的位置 return (i + 1); } // 快速排序递归函数 void quickSort(int arr[], int low, int high) { if (low < high) { int pi = partition(arr, low, high); // 获取区后的基准值索引 // 对基准值左右两边的子数组递归调用快速排序 quickSort(arr, low, pi - 1); quickSort(arr, pi + 1, high); } } // 打印数组辅助函数 void printArray(int arr[], int size) { for (int i = 0; i < size; i++) cout << arr[i] << " "; cout << endl; } // 主函数测试 int main() { int data[] = {8, 7, 2, 1, 0, 9, 6}; int n = sizeof(data) / sizeof(data[0]); cout << "Unsorted Array:\n"; printArray(data, n); quickSort(data, 0, n - 1); cout << "\nSorted Array in Ascending Order:\n"; printArray(data, n); } ``` --- ### 小区间优化 为了进一步提升快速排序的性能,在处理小规模子数组时可以引入其他简单排序算法代替递归调用快速排序。常见的做法是在子数组长度小于某个阈值(如 10 或 15)时改用插入排序,因为后者在这种场景下表现更好[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值