快速排序(Quick Sort)是一种常用的排序算法,也是数据结构中的重要内容之一。它采用基准值(pivot)把待排序数组分成两个子数组,并递归调用本身对两个子数组分别进行排序,直至每个子数组只有一个元素或为空。本文将从多个角度分析快速排序每一趟过程。
1. 基本流程
快速排序的基本流程如下:
(1)选取基准元素
从待排数组中任选一个元素,作为基准元素。
(2)划分区间
将待排数组中除基准元素外的所有元素,按照大小关系划分到基准元素的左侧或右侧。划分可以使用两个指针i、j,分别从待排数组的两端开始扫描,并交换i、j指向的元素。
(3)递归排序
对基准元素左侧和右侧的子数组,重复上述过程,递归进行快速排序操作。
(4)合并数组
将基准元素与左右子数组合并得到完整排序数组。
2. 详细过程
假设我们要对数组[5, 2, 8, 3, 9, 1, 7, 4, 6]进行快速排序,以第一个元素5作为基准元素。根据划分规则,小于5的元素在基准元素左侧,大于5的元素在基准元素右侧。
第一趟排序前:
[5, 2, 8, 3, 9, 1, 7, 4, 6]
第一趟排序后:
[1, 2, 4, 3, 5, 8, 7, 9, 6]
可以看到,第一趟排序后,数组被分成了两个子数组[1,2,4,3]和[8,7,9,6],并且5已经在排好序的位置上。接下来,我们要对两个子数组分别进行快速排序。
第二趟排序前:
[1, 2, 4, 3] [8, 7, 9, 6]
第二趟排序后:
[1, 2, 3, 4] [6, 7, 8, 9]
第三趟排序前:
[1, 2, 3] [6, 7, 8, 9]
第三趟排序后:
[1, 2, 3] [6, 7, 8, 9]
第四趟排序前:
[1, 2] [3]
[6, 7, 8] [9]
第四趟排序后:
[1, 2] [3]
[6, 7, 8] [9]
第五趟排序前:
[1] [2]
[6, 7] [8]
第五趟排序后:
[1] [2]
[6, 7] [8]
第六趟排序前:
[6] [7]
第六趟排序后:
[6] [7]
最后,将子数组合并得到完整排序数组。
3. 时间复杂度
快速排序的时间复杂度是O(nlogn),其中n是待排数组的长度。这是因为每一趟排序都将待排数组分成两个子数组,所以一共要进行logn趟排序。每趟排序要扫描整个子数组,时间复杂度为O(n)。因此,快速排序的总时间复杂度是O(nlogn)。
4. 空间复杂度
快速排序的空间复杂度是O(logn),其中logn是递归栈的深度。因为每一趟排序需要调用两次快速排序,所以递归栈的深度为logn。在最坏情况下,即数组已经有序或者基准元素选取不当的情况下,递归栈的深度可能达到n。但是,在平均情况下,递归栈的深度是logn,空间复杂度是O(logn)。
5. 稳定性
快速排序是不稳定的排序算法。因为在划分过程中,可能会破坏相同元素的相对位置。例如,对数组[3, 1, 3, 2]进行快速排序,以第一个元素3作为基准元素,第一趟排序后,数组变成了[2, 1, 3, 3]。第二趟排序后,数组变成了[1, 2, 3, 3]。可以看到,相同的元素3的相对位置被破坏了。
扫码咨询 领取资料