一、算法简介
快速排序是一种高效的排序算法,采用分治策略。它通过选定一个“基准”值,将数组划分为小于和大于基准的两部分,递归地对这两部分进行排序,最终实现整个数组的有序排列。
二、C语言实现要点
-
基准值选择:常见的选择有数组的第一个元素、最后一个元素或中间元素等。不同的选择方式会影响排序效率。
-
分区操作:通过交换元素,将小于基准的元素移到基准左侧,大于基准的元素移到右侧。
-
递归排序:对划分后的两部分分别递归调用快速排序函数,直至数组完全排序。
三、时间复杂度
-
平均情况:O(nlogn),性能优越。
-
最坏情况:O(n²),但可通过优化(如三数取中法选择基准)降低出现概率。
四、具体步骤
1. 选择基准值
从数组中选择一个元素作为基准值。常见的选择方法有:
-
选择第一个元素:简单直接,但可能导致性能问题。
-
选择最后一个元素:同样简单,但性能问题依然存在。
-
三数取中法:选择数组的第一个、中间和最后一个元素的中值作为基准,可以有效避免最坏情况。
2. 分区操作(Partition)
分区操作是快速排序的关键步骤。其目的是将数组划分为两部分,一部分包含小于基准值的元素,另一部分包含大于基准值的元素。具体步骤如下:
-
初始化两个指针,
i
和j
,分别指向数组的起始位置和结束位置。 -
从左到右遍历数组,找到第一个大于基准值的元素。
-
从右到左遍历数组,找到第一个小于基准值的元素。
-
如果这两个元素的索引没有交叉,交换它们的位置。
-
重复上述步骤,直到两个指针交叉。此时,将基准值放到交叉点的位置。
3. 递归排序
将数组划分为两部分后,对这两部分分别递归调用快速排序函数。递归的终止条件是数组的长度小于等于1,此时数组已经有序。
五、代码实现
void quick_sort(int *arr ,int left,int right)
{
//递归结束条件:当左指针的位置大于等于右指针则结束递归
if (left>=right)
{
return ;
}
int i=left;
int j=right;
//以最左侧的数值位基准,找到其合适的位置
int temp=arr[left];
while (i < j) {
// 从右向左找到第一个小于基准值的元素
while (i < j && arr[j] >= temp) {
j--;
}
// 从左向右找到第一个大于基准值的元素
while (i < j && arr[i] <= temp) {
i++;
}
// 交换这两个元素
if (i < j) {
swap(&arr[i], &arr[j]);
}
}
//找到基准值的正确位置,交换
swap(&arr[i],&arr[left]);
//交换后基准值左侧的值全小于等于他,右侧的值全大于等于他
//将左右两侧看为单独的区间,进行递归处理
quick_sort(arr,left,i-1);
quick_sort(arr,i+1,right);
}