作者介绍
我是长春理工大学计算机研0小棠学姐,今天为大家带来快速排序的排序方法。
快速排序(Quick Sort)是一种高效的排序算法,采用分而治之(Divide and Conquer)的策略来把一个序列分为两个子序列,步骤为:
快速排序的步骤
- 选择基准(Pivot):从数列中挑出一个元素,称为“基准”(pivot),
- 分区(Partitioning):重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。
- 递归(Recursion):递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。
递归的最底部情形,是数列的大小是零或一,也就是已经排序好。虽然一直递归下去,但是这个算法总会结束,因为在每次的迭代中,它至少会把一个元素摆到它最后的位置去。
#include <stdio.h>
// 函数声明
void quickSort(int A[], int low, int high);
int partition(int A[], int low, int high);
void swap(int *a, int *b);
// 主函数
int main() {
int arr[] = {10, 7, 8, 9, 1, 5};
int n = sizeof(arr)/sizeof(arr[0]);
quickSort(arr, 0, n-1);
printf("Sorted array: \n");
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
return 0;
}
// 快速排序函数
void quickSort(int A[], int low, int high) {
if (low < high) {
// pi 是分区操作后基准的索引
int pi = partition(A, low, high);
// 递归地对基准左边的子数组进行快速排序
quickSort(A, low, pi - 1);
// 递归地对基准右边的子数组进行快速排序
quickSort(A, pi + 1, high);
}
}
// 分区函数
int partition(int A[], int low, int high) {
// 选择最右端的元素作为基准
int pivot = A[high];
// i 是小于基准的元素的右边界的索引
int i = low - 1;
for (int j = low; j <= high - 1; j++) {
// 如果当前元素小于或等于基准
if (A[j] <= pivot) {
i++; // 移动右边界
swap(&A[i], &A[j]); // 交换 A[i] 和 A[j]
}
}
// 交换 A[i+1] 和 A[high](即基准)
swap(&A[i + 1], &A[high]);
// 返回基准的索引
return i + 1;
}
// 交换两个整数的值
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
快速排序的性能
- 最好情况:每次分区操作都能把数组分成大小接近相等的两部分,此时时间复杂度为O(nlogn)。
- 最坏情况:每次分区操作选取的基准都是当前未排序部分的最小(或最大)元素,导致每次分区操作只得到一个元素的子数组,此时时间复杂度退化为O(n^2)。
- 平均情况:时间复杂度为O(nlogn)。
由于快速排序的性能高度依赖于基准的选择,因此在实际应用中,通常会采用一些策略来优化基准的选择,如“三数取中”等,以提高算法的平均性能。此外,快速排序也是一种不稳定的排序算法,即相等的元素可能在排序后的序列中改变相对位置。
快速排序的案例
假设我们仍然使用序列 [8, 4, 23, 42, 16, 15]
,并且每次都选择最后一个元素作为基准。
第一轮排序
- 基准(pivot)是
15
- 分区后,小于
15
的元素移到左边,大于15
的元素移到右边 - 排序后(包括基准的位置):
[4, 8, 15, 42, 16, 23]
- 左边
[4, 8]
已经是“有序”的(相对于基准15
来说) - 右边
[42, 16, 23]
需要进一步处理
- 左边
第二轮排序(对右边部分 [42, 16, 23]
进行)
- 基准(pivot)是
23
- 分区后
- 排序后(包括基准的位置):假设为
[..., 16, 23, 42, ...]
(注意,这里我省略了左边的部分,因为它已经是有序的,或者至少与当前轮次的操作无关)- 左边(相对于基准
23
)的[16]
是“有序”的 - 右边(只有一个元素
42
)自然也是“有序”的
- 左边(相对于基准
联系方式
如想要报考长春理工大学计算机专业的准研究生可联系我179+234+8035
也可直接加25长春理工大学计算机和人工智能专业考研🐧讨论85881++8904