排序算法---快速排序
原创不易,转载请注明出处。欢迎点赞收藏~
快速排序是一种常用的排序算法,采用分治的策略来进行排序。它的基本思想是选取一个元素作为基准(通常是数组中的第一个元素),然后将数组分割成两部分,其中一部分的所有元素小于等于基准值,另一部分的所有元素大于基准值。然后对这两部分继续递归应用快速排序算法,直到整个数组有序。
算法步骤如下:
- 选择基准元素。
- 将数组分割成两部分,使得左半部分的元素都小于等于基准值,右半部分的元素都大于基准值。
- 对左右两部分分别应用快速排序算法(递归)。
快速排序的时间复杂度为O(nlogn)。这是因为每次划分操作会把待排序的序列分割成两个规模大致相等的子序列,划分操作的时间复杂度为O(n),递归调用的次数为O(logn)。所以总体的时间复杂度为O(nlogn)。
快速排序的空间复杂度为O(logn)。这是因为快速排序需要使用递归来进行划分操作,每一层递归都需要额外的空间来保存分割点的位置,递归调用的次数为O(logn),所以总体的空间复杂度为O(logn)。
需要注意的是,快速排序是一种原地排序算法,它不需要额外的辅助空间来进行排序。但是在实际实现中,为了提高排序的效率和减少递归深度,通常会使用一些优化策略,比如随机选择基准元素、三数取中法等。
#include <stdio.h>
// 交换函数,用于交换数组中两个元素的位置
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
// 分割函数,用于将数组分割成左右两部分
int partition(int arr[], int low, int high)
{
int pivot = arr[low]; // 选择第一个元素作为基准值
int i = low, j = high;
while (i < j)
{
// 从右往左找到第一个小于基准值的元素
while (i < j && arr[j] >= pivot)
{
j--;
}
// 从左往右找到第一个大于基准值的元素
while (i < j && arr[i] <= pivot)
{
i++;
}
// 交换这两个元素的位置
if (i < j)
{
swap(&arr[i], &arr[j]);
}
}
// 将基准值放到最终的位置
swap(&arr[low], &arr[i]);
return i;
}
// 快速排序函数
void quick_sort(int arr[], int low, int high)
{
if (low < high)
{
// 找到分割点
int pivotIndex = partition(arr, low, high);
// 对分割点左右两部分进行递归排序
quick_sort(arr, low, pivotIndex - 1);
quick_sort(arr, pivotIndex + 1, high);
}
}
// 测试
int main()
{
int arr[] = {8, 4, 2, 9, 5, 1, 6, 3, 7};
int n = sizeof(arr) / sizeof(arr[0]);
printf("排序前的数组:\n");
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
quick_sort(arr, 0, n - 1);
printf("\n排序后的数组:\n");
for (int i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
putchar('\n');
return 0;
}
以上示例代码演示了如何使用快速排序算法对一个整数数组进行排序。首先定义了交换函数swap
用于交换数组中两个元素的位置,然后定义了分割函数partition
用于将数组分割成左右两部分。 最后定义了快速排序函数quick_sort来递归地进行分割和排序。
运行示例代码后,你可以看到以下输出: