C 语言快速排序算法详解与优化实现
快速排序是 C 语言标准库中常用的排序算法之一,以其平均时间复杂度 O(N log N) 和原地排序特性被广泛使用。本文将深入剖析其原理,从基础 Hoare 分区法到三数取中、小区间优化及非递归实现,提供完整的工程实践代码。
一、快速排序基础(Hoare 分区)
1. 核心思想
快速排序的核心在于选取一个基准值(Key),通过交换操作将数组划分为两部分:左侧所有元素小于 Key,右侧所有元素大于 Key。随后对左右两个子区间递归执行相同操作,直到区间长度为 1。
2. 实现思路
采用双指针法(L 和 R):
- 右指针 R 向左移动,寻找比 Key 小的值;
- 左指针 L 向右移动,寻找比 Key 大的值;
- 相遇时停止,交换 Key 与相遇点元素,完成一次分区。
3. 代码实现
void QuickSort1(int* a, int left, int right)
{
if (left >= right)
return;
int key = left;
int L = left;
int R = right;
while (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[right], &a[key]);
key = right;
QuickSort1(a, L, key - 1);
QuickSort1(a, key + 1, R);
}
二、快速排序进阶(三数取中)
1. 存在的问题
若固定选择第一个元素为 Key,当数组已有序或接近有序时,分区极不均匀,导致时间复杂度退化为 O(N^2)。
2. 优化方案:三数取中
选取数组首、尾、中间三个位置的值,取其中位数作为 Key。这能有效避免极端情况下的性能下降。
3. 代码实现
int FindKey(int* a, int left, int right)
{
int mid = (left + right) / 2;
if (a[left] > a[right])
{
if (a[right] > a[mid])
return right;
(a[mid] > a[left])
left;
mid;
}
{
(a[left] > a[mid])
left;
(a[mid] > a[right])
right;
mid;
}
}
{
(left >= right)
;
L = left;
R = right;
key = FindKey(a, left, right);
Swap(&a[key], &a[left]);
key = left;
(left < right)
{
(left < right && a[right] >= a[key])
right--;
(left < right && a[left] <= a[key])
left++;
Swap(&a[left], &a[right]);
}
Swap(&a[right], &a[key]);
key = right;
QuickSort1(a, L, key - );
QuickSort1(a, key + , R);
}


