了解快速排序算法

    在本教程中,您将学习快速排序的工作原理。另外,您还将找到使用C语言的示例。
    Quicksort是一种基于分治方法的算法,它将数组分割成子数组,并递归调用这些子数组对元素进行排序。

快速排序算法如何工作?
  1. 从数组中选择轴心元素。可以从数组中选择任何元素作为轴心元素。
    在这里,我们把数组最右边(即最后一个元素)作为轴心元素。
    在这里插入图片描述

  2. 小于轴心元素的元素放在左侧,大于轴心元素的元素放在右侧。
    在这里插入图片描述
    通过以下步骤实现上述安排。
    a. 指针固定在轴心元素上。轴心元素与第一个索引指示的元素进行比较。如果该元素大于轴心元素,则将第二个指针指向该元素。
    b. 现在,轴心元素与其他元素(第三个指针)进行比较。如果当前元素小于轴心元素,则将较小的元素与先前找到的较大元素交换。
    在这里插入图片描述
    c. 这个过程一直持续到最后一个元素。
    最后,轴心元素与第二个指针交换。
    在这里插入图片描述
    d. 现在,这个轴心元素的左、右两个子部分将在下面的步骤中进行进一步处理。

  3. 再次分别为左侧和右侧子部分选择轴心元素。在这些子部分中,轴心元素放置在正确的位置。然后,重复步骤2。
    在这里插入图片描述

  4. 子部分再次被划分为更小的子部分,直到每个子部分由单个元素构成。

  5. 此时,数组已经排序。

快速排序使用递归对子部分进行排序

    在分治法的基础上,快速排序算法可以解释为:

  • 划分
    以轴心为划分点,将数组划分为若干个子部分。小于轴心的元素放置在轴心的左侧,大于轴心的元素放置在轴心的右侧。
  • 控制
    通过为左、右子部分选择轴心元素,再次对其进行分治。这可以通过递归地将子部分传递给算法中来实现。
  • 组合
    此步骤在快速排序中不起重要作用。阵列已经在控制步骤结束时排序。

    借助下面的插图,您可以理解快速排序的工作原理。
在这里插入图片描述
    使用递归对轴心元素左边的元素进行排序
在这里插入图片描述
    使用递归对轴心元素右侧的元素进行排序

快速排序算法伪代码
quickSort(array, leftmostIndex, rightmostIndex)
  if (leftmostIndex < rightmostIndex)
    pivotIndex <- partition(array,leftmostIndex, rightmostIndex)
    quickSort(array, leftmostIndex, pivotIndex)
    quickSort(array, pivotIndex + 1, rightmostIndex)

partition(array, leftmostIndex, rightmostIndex)
  set rightmostIndex as pivotIndex
  storeIndex <- leftmostIndex - 1
  for i <- leftmostIndex + 1 to rightmostIndex
  if element[i] < pivotElement
    swap element[i] and element[storeIndex]
    storeIndex++
  swap pivotElement and element[storeIndex+1]
return storeIndex + 1
C示例
// Quick sort in C

#include <stdio.h>

// Function to swap position of elements
void swap(int *a, int *b) {
  int t = *a;
  *a = *b;
  *b = t;
}

// Function to partition the array on the basis of pivot element
int partition(int array[], int low, int high) {
  
  // Select the pivot element
  int pivot = array[high];
  int i = (low - 1);

  // Put the elements smaller than pivot on the left 
  // and greater than pivot on the right of pivot
  for (int j = low; j < high; j++) {
    if (array[j] <= pivot) {
      i++;
      swap(&array[i], &array[j]);
    }
  }

  swap(&array[i + 1], &array[high]);
  return (i + 1);
}

void quickSort(int array[], int low, int high) {
  if (low < high) {
    
    // Select pivot position and put all the elements smaller 
    // than pivot on left and greater than pivot on right
    int pi = partition(array, low, high);
    
    // Sort the elements on the left of pivot
    quickSort(array, low, pi - 1);
    
    // Sort the elements on the right of pivot
    quickSort(array, pi + 1, high);
  }
}

// Function to print eklements of an array
void printArray(int array[], int size) {
  for (int i = 0; i < size; ++i) {
    printf("%d  ", array[i]);
  }
  printf("\n");
}

// Driver code
int main() {
  int data[] = {8, 7, 2, 1, 0, 9, 6};
  int n = sizeof(data) / sizeof(data[0]);
  quickSort(data, 0, n - 1);
  printf("Sorted array in ascending order: \n");
  printArray(data, n);
}
快速排序的复杂度

    时间复杂度

  • 最坏情况复杂度[Big-O]:O( n 2 n^2 n2
    当选取的轴心元素是最大或最小的元素时发生。
    这种情况导致轴心元素位于排序数组的最末端。一个子数组总是空的,另一个子数组包含 n-1 个元素。因此,仅对该子数组调用快速排序。
    然而,对于散乱的轴心,快速排序算法有更好的性能。
  • 最佳情况复杂度[大Ω]:O(n*log n)
    当轴心元素始终是中间元素或靠近中间元素时为最佳情况复杂度。
  • 平均情况复杂度[大θ]:O(n*logn)
    当上述两种情况不发生时,为平均情况复杂度。

    空间复杂度
    quicksort的空间复杂度为O(log n)。

快速排序算法的应用

    当出现以下情况时,使用快速排序算法:

  • 编程语言有利于递归
  • 时间复杂度很重要
  • 空间复杂度很重要
参考文档

[1]Parewa Labs Pvt. Ltd.Quicksort Algorithm[EB/OL].https://www.programiz.com/dsa/quick-sort,2020-01-01.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值