网络

教育改变生活

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 730|回复: 0
打印 上一主题 下一主题

【C语言】快速排序

[复制链接]

711

主题

718

帖子

3204

积分

版主

Rank: 7Rank: 7Rank: 7

积分
3204
跳转到指定楼层
楼主
发表于 2025-3-10 20:43:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
快速排序是一种高效的基于比较的排序算法,C语言是快速排序的实现语言之一。在本文中,我们将详细介绍C语言实现快速排序的步骤以及代码,并分析其时间复杂度。
实现步骤

快速排序的实现分为两个主要步骤:选择基准元素和分割序列。

选择基准元素


选择基准元素是快速排序的关键步骤。基准元素的选择会直接影响算法的效率。一般情况下,我们可以选取待排序序列的第一个元素作为基准元素,但这种方式可能会导致最坏情况的出现,即待排序序列已经有序或近乎有序,此时时间复杂度将退化为O(n^2)。

为了避免最坏情况的出现,我们可以采用一些随机化的方法来选择基准元素,例如随机选取一个元素作为基准元素,或者从待排序序列中随机选择三个元素,取它们的中位数作为基准元素。

分割序列


在选择基准元素之后,我们需要将待排序序列分割成两个子序列。具体而言,我们可以维护两个指针,一个指向待排序序列的头部,一个指向序列的尾部。然后分别从两端开始扫描序列,当找到一个元素比基准元素大(或小)时,就将其与另一个元素交换位置。重复这个过程,直到两个指针相遇为止。此时,我们可以将基准元素和相遇位置上的元素交换位置,然后将序列分成左右两部分,左边的部分的所有元素都小于等于基准元素,右边的部分的所有元素都大于等于基准元素。

递归排序
接下来,我们可以递归地对左右两个子序列进行快速排序,直到序列有序为止。

C语言实现


下面是C语言实现快速排序的代码:
  • #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 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) {
  •     int i;
  •     for (i = 0; i < size; i++) printf("%d ", arr[i]);
  •     printf("\n");
  • }
  • 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: ");
  •     printArray(arr, n);
  •     return 0;
  • }


在这个代码中,我们首先定义了一个函数 swap,用于交换两个元素的值。然后,我们定义了一个函数 partition,该函数用于将待排序序列分割成两个子序列,并返回基准元素的位置。最后,我们定义了一个函数quicksort,该函数用于递归地对左右两个子序列进行快速排序。

在 quicksort 函数中,我们首先判断待排序序列是否为空,如果不为空,就调用 partition 函数将序列分割成两个子序列,然后递归地对左右两个子序列进行排序。在主函数中,我们定义了一个整数数组,并对其进行快速排序,最后输出排序后的数组。

时间复杂度分析


快速排序的时间复杂度取决于基准元素的选择方式。在最坏情况下,基准元素被选择为序列中的最小(或最大)元素,此时每次分割只能减少一个元素,需要进行 n 次分割才能完成排序,时间复杂度为 O(n^2)。在最好情况下,基准元素被选择为序列的中位数,此时每次分割将序列平均分成两部分,需要进行 log n 次分割才能完成排序,时间复杂度为 O(n log n)。

由于快速排序采用分治的思想,每次将序列分割成两个子序列进行排序,因此快速排序的时间复杂度为 O(n log n)。快速排序的空间复杂度主要取决于递归调用的层数,即分割的次数,最坏情况下需要进行 n 次分割,因此空间复杂度为 O(n)。

需要注意的是,在实际应用中,快速排序可能存在一些问题,比如当待排序序列中存在大量重复元素时,快速排序的效率会变得很低。为了解决这个问题,可以使用三路快速排序(即将序列分成小于、等于和大于基准元素三个部分进行排序),或者使用其他的排序算法。

总结


快速排序是一种高效的排序算法,它采用分治的思想,每次将序列分割成两个子序列进行排序,时间复杂度为 O(n log n),空间复杂度为 O(n)。

快速排序的实现相对简单,但需要注意一些细节,比如基准元素的选择方式和数组越界的问题。在实际应用中,快速排序可能存在一些问题,需要结合具体情况选择合适的排序算法。


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

WEB前端

QQ|手机版|小黑屋|金桨网|助学堂  咨询请联系站长。

GMT+8, 2025-4-5 03:17 , Processed in 0.034356 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表