C语言下快速排序(挖坑法)详解

C语言下快速排序(挖坑法)详解

什么是快速排序

快速排序是将一个待排序的序列分成两部分,其中一部分的所有元素都比另一部分的所有元素小,然后再对这两部分分别进行排序,递归执行该操作直到将整个序列排好为止。快速排序使用了分治思想。由于在每一次的递归过程中,都将待排序的序列分成两部分,因此处理的数据量不断减少,使得算法的效率比较高。

快速排序的实现

挖坑法

挖坑法的基本思想是首先选择一个基准数,用两个标记i和j从序列两端分别向中间扫描,当i遇到了比基准数大的数就停下来,当j遇到了比基准数小的数就停下来,然后交换i和j所指向的元素。直到i和j重合,此时就可以将基准数放在这个位置上,以此将序列分成两个子序列,然后递归地对这两个子序列进行排序。

具体实现的过程如下:

首先选择序列的第一个元素作为基准数pivot,设定i和j的初始值分别为左端点left和右端点right,然后从j开始,向左扫描序列,找出第一个小于基准数的元素,停在j位置上,这时候将pivot的值赋给i,实现了一个“挖坑”操作。接着,从i开始,向右扫描序列,找出第一个大于基准数的元素,停在i位置上,这时候就可以将j位置上的元素填到这个坑中,实现了一个“填坑”操作。随后,i和j再次向中间移动,继续扫描序列,直到i和j重合。最后,将pivot放在i/j重合的位置上,这样就将序列分成了两部分,并以此递归执行。

下面是基于挖坑法的快速排序的代码实现:

void QuickSort(int arr[], int left, int right) {
    if (left >= right) return; // 如果序列只剩下一个元素或者没有元素,则直接返回
    int i = left, j = right, pivot = arr[left]; // 初始化指针i、j,以及基准数pivot
    while (i < j) {
        while (arr[j] >= pivot && i < j) j--;
        if (i < j) arr[i++] = arr[j]; // 挖坑
        while (arr[i] <= pivot && i < j) i++;
        if (i < j) arr[j--] = arr[i]; // 填坑
    }
    arr[i] = pivot; // 将基准数放入最后的空位
    QuickSort(arr, left, i - 1); // 递归排序左边的子序列
    QuickSort(arr, i + 1, right); // 递归排序右边的子序列
}

示例说明

示例一

给定一个数组 arr = {6, 2, 7, 3, 8, 9, 4, 5, 1},使用快速排序对其进行从小到大排序。

首先选定 arr[0],即6作为基准数pivot。然后i和j指向数组的两端 left = 0, right = 8。从j开始,往左寻找第一个小于pivot的数,即找到了 arr[6] = 4,同时将 arr[0] 填上这个坑,得到 arr[0, 2, 7, 3, 8, 9, 4, 5, 4];接着,从i开始,往右寻找第一个大于pivot的数,即找到了 arr[1] = 2,同时将 arr[6] 填上这个坑,得到 arr[2, 2, 7, 3, 8, 9, 6, 5, 4]。i和j在此时重合,将pivot放在这个位置上,得到了 arr[2, 2, 4, 3, 1, 5, 6, 7, 9, 8]。此时将序列分成了两部分,左半部分都小于pivot,右半部分都大于pivot,递归进行排序即可。

经过一次分割后,左半部分为 {2, 2, 4, 3, 1},右半部分为 {5, 6, 7, 9, 8}。以左半部分为例,选择 arr[0] 作为基准数pivot,进行相同的操作,即先从右向左找到一个小于pivot的数 arr[3] = 3,用 arr[0] 填坑,得到 arr[1, 2, 4, 3, 1];接着再从左向右找到第一个大于pivot的数 arr[2] = 4,用 arr[3] 填坑,得到 arr[1, 2, 3, 4, 1]。此时将pivot放在最后的位置上,得到 arr[1, 2, 3, 4, 6]。随后对右半部分进行相似的操作,最终得到完整的排好序的数组 arr[1, 2, 3, 4, 5, 6, 7, 8, 9]

示例二

给定一个数组 arr = {9, 8, 7, 6, 5, 4, 3, 2, 1},使用快速排序对其进行从大到小排序。

首先选定 arr[0],即9作为基准数pivot。然后i和j指向数组的两端 left = 0, right = 8,从j开始寻找小于pivot的数,由于数组本身就是从大到小排列的,因此找不到小于9的数。接着,从i开始寻找大于pivot的数,找到了 arr[1] = 8,用 arr[0] 填坑,得到 arr[9, 9, 7, 6, 5, 4, 3, 2, 1],继续寻找直到i和j重合,最后将pivot放在此位置上,即 arr[8, 9, 7, 6, 5, 4, 3, 2, 1]。此时将序列分成了两部分,左半部分都大于pivot,右半部分都小于pivot,以此递归进行后续排序。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言下快速排序(挖坑法)详解 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • JavaScript实现快速排序(自已编写)

    下面是详细的讲解JavaScript实现快速排序的完整攻略。 1. 什么是快速排序? 快速排序是一种常用的排序算法,通过分割(partition)和递归分治的思想来快速排序一个数组,在平均情况下它的时间复杂度为 $O(n\log n)$,也是一种不稳定的排序方法。 2. 快速排序的实现过程 2.1 分割 对一个数组进行快速排序的过程就是先将其从中间分割成两部…

    算法与数据结构 2023年5月19日
    00
  • go实现冒泡排序算法

    下面是详细讲解Go语言实现冒泡排序算法的完整攻略: 1. 什么是冒泡排序? 冒泡排序是一种基于交换的排序算法,算法通过比较相邻的元素,将比较大的元素交换到后面,从而达到排序的目的。这个过程就像是水中不断上冒的气泡,因此称之为冒泡排序。 冒泡排序是经典的排序算法之一,它虽然时间复杂度高达 O(n^2),但其思想简单,易于理解和实现,并且在某些特殊的情况下,它的…

    算法与数据结构 2023年5月19日
    00
  • Python中利用sorted()函数排序的简单教程

    下面是我为您准备的Python中利用sorted()函数排序的简单教程。 1. sorted()函数的简介 sorted()函数是Python内置函数之一,用于对一个可迭代对象进行排序操作。这个函数返回一个新的列表,而不会修改原来的列表本身。 sorted()函数的基本语法如下所示: sorted(iterable, key=None, reverse=Fa…

    算法与数据结构 2023年5月19日
    00
  • PHP实现常用排序算法的方法

    一、常用排序算法 常见的排序算法包括冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序等。 冒泡排序: 基本思想是每次比较相邻的两个元素,如果前者比后者大,则将它们交换位置,最终使得从左到右的每个元素都是当前序列中最小的。 选择排序: 基本思想是每次从未排序的数中选取最小的数,并将其放到已排序序列的末尾。 插入排序: 基本思想是从无序序列中取…

    算法与数据结构 2023年5月19日
    00
  • C语言常见排序算法之插入排序(直接插入排序,希尔排序)

    接下来我将为大家详细讲解“C语言常见排序算法之插入排序(直接插入排序, 希尔排序)”。 直接插入排序 算法思路 直接插入排序算法的实现思路是:将一个无序的数据序列分为一个有序子序列和一个无序子序列两部分,将无序子序列的元素一个一个插入到有序子序列中,直到插入完所有元素,最终形成一个新的有序序列。在具体编写代码时,我们会将数据序列看作是一个数组来进行操作。 代…

    算法与数据结构 2023年5月19日
    00
  • 2019年京东前端工程师面试题(附答案)

    本次将会以京东前端工程师面试题为例,详细讲解如何准备和应对前端岗面试。 第一步:了解面试整体流程和考察的技能点 在准备面试前,需要先了解面试的整体流程和所考察的技能点,从而根据需要和缺点来进行有针对性的准备。 面试的整体流程一般包括: 自我介绍和岗位广告 聊聊项目和技术栈 问题解答和技术评测 算法/编码能力测试 HR面试 而在前端工程师的岗位面试中,考察的技…

    算法与数据结构 2023年5月19日
    00
  • PHP有序表查找之二分查找(折半查找)算法示例

    下面我将对“PHP有序表查找之二分查找(折半查找)算法示例”的完整攻略进行详细讲解。 一、什么是二分查找 二分查找又称为折半查找,是一种在有序数组中查找某一特定元素的搜索算法。基本思想是:将有序数组分成两部分,如果要查找的元素比数组中间的元素小,则在左半部分继续查找;如果要查找的元素比数组中间的元素大,则在右半部分继续查找,直到找到或者查找结束。 二分查找算…

    算法与数据结构 2023年5月19日
    00
  • C语言实现快速排序算法实例

    下面是“C语言实现快速排序算法实例”的完整攻略: 快速排序算法简介 快速排序是一种高效的排序算法,属于比较排序中的一种,采用分治策略,通过将原序列划分为若干个子序列依次排序,最终得到有序序列。该算法的平均时间复杂度为O(nlogn),最坏情况下的时间复杂度为O(n^2),因此在实际应用中要根据数据规模和数据分布情况选择合适的算法。 C语言快速排序实现示例 下…

    算法与数据结构 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部