双路快速排序

You:

双路快速排序 、思路、C 代码、复杂度


双路快速排序:

双路快速排序是快速排序算法的一种改进版本,它通过使用两个指针,分别从数组的两端向中间移动,以实现更好的性能。下面是其思路、C代码以及解释:

思路:

  1. 选择数组中的一个元素作为基准值(通常选择第一个或最后一个元素)。
  2. 使用两个指针,一个从数组的起始位置开始向后移动(称为左指针),一个从数组的末尾位置开始向前移动(称为右指针)。
  3. 左指针向后移动,直到找到一个比基准值大的元素。
  4. 右指针向前移动,直到找到一个比基准值小的元素。
  5. 交换左右指针所指向的元素。
  6. 重复步骤 3、4、5,直到左指针超过了右指针。
  7. 最后将基准值与右指针所指向的元素交换位置,将数组分为两部分。
  8. 对左右两部分分别递归地进行快速排序。

C代码:

#include <stdio.h>

// 交换数组中两个元素的值
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// 双路快速排序函数
void quickSort(int arr[], int low, int high) {
    if (low >= high) return;

    int pivot = arr[low]; // 选择第一个元素作为基准值
    int i = low + 1; // 左指针
    int j = high; // 右指针

    while (1) {
        // 从左向右找到第一个大于等于基准值的元素
        while (i <= high && arr[i] < pivot) i++;
        // 从右向左找到第一个小于等于基准值的元素
        while (j >= low + 1 && arr[j] > pivot) j--;

        if (i > j) break; // 如果左指针超过了右指针,则退出循环

        // 交换左右指针所指向的元素
        swap(&arr[i], &arr[j]);
        i++;
        j--;
    }

    // 将基准值放到正确的位置上
    swap(&arr[low], &arr[j]);

    // 对左右两部分分别进行递归排序
    quickSort(arr, low, j - 1);
    quickSort(arr, j + 1, high);
}

// 打印数组元素
void printArray(int arr[], int size) {
    for (int i = 0; i < size; ++i)
        printf("%d ", arr[i]);
    printf("\n");
}

int main() {
    int arr[] = {5, 2, 6, 1, 3, 9, 4, 7, 8};
    int n = sizeof(arr) / sizeof(arr[0]);
    printf("Original array: \n");
    printArray(arr, n);
    quickSort(arr, 0, n - 1);
    printf("Sorted array: \n");
    printArray(arr, n);
    return 0;
}

解释:

  • swap() 函数用于交换数组中的两个元素的值。
  • quickSort() 函数是双路快速排序的核心实现。它使用了双指针来在数组中找到合适的位置来放置基准值,并进行递归调用来对左右两部分进行排序。
  • printArray() 函数用于打印数组元素。
  • main() 函数中,我们定义了一个数组并调用 quickSort() 函数来对数组进行排序,然后打印排序后的结果。

时间复杂度和空间复杂度计算:

双路快速排序的时间复杂度和空间复杂度如下:

时间复杂度:

  • 最佳情况时间复杂度:O(nlogn)
  • 平均情况时间复杂度:O(nlogn)
  • 最坏情况时间复杂度:O(n^2)

在最佳和平均情况下,双路快速排序的时间复杂度为 O(nlogn),这是因为每次划分都能将数组均匀地划分成两部分,使得每次递归调用的规模约为原始数组的一半。但在最坏情况下,即当数组已经有序或基本有序时,每次划分都只能将数组划分为一个小部分和一个大部分,这会导致递归调用树呈现线性结构,使得时间复杂度变为 O(n^2)。

空间复杂度:

双路快速排序是原地排序算法,它只需要常量级别的额外空间来存储指针和基准值的位置,因此空间复杂度为 O(1),即为常数级别。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值