快速排序是一种常用的基于比较的排序算法,它通过对数组元素的不断交换和划分,以达到将一个无序的数组转化成一个有序的数组的目的。它不像插入排序或者冒泡排序一样,逐一比较相邻元素的大小,而是通过分治思想,先将整个数组按照一个中间值分为两部分,再对这两部分分别进行快速排序,直到整个数组有序。
下面是一份简单易懂的快速排序代码:
```python
def quick_sort(arr: list, left: int, right: int) -> list:
if left < right:
pivot_index = partition(arr, left, right)
quick_sort(arr, left, pivot_index-1)
quick_sort(arr, pivot_index+1, right)
return arr
def partition(arr: list, left: int, right: int) -> int:
pivot = arr[left]
i, j = left+1, right # 左右指针
while True:
while i <= right and arr[i] < pivot:
i += 1
while j >= left+1 and arr[j] > pivot:
j -= 1
if i > j:
break
arr[i], arr[j] = arr[j], arr[i]
i += 1
j -= 1
arr[left], arr[j] = arr[j], arr[left]
return j
```
快速排序通过基准元素的选择,对数据的分割能力影响很大,如果选择得当,算法复杂度可能会得到很好的优化。下面就从几个角度分析快排的代码实现。
1. 基准元素的选择
快排算法需要在待排序的元素中选择一个中间数作为基准元素,然后把小于基准元素的数放到基准元素左边,大于基准元素的数放到右边。通常情况下,选择中间数作为基准元素是比较合适的,但在最差情况下,即选择的基准元素是数组中的最小或最大值时,快排的时间复杂度会比较高。
为了避免这种情况,可以采用三数中值法或随机法来选择基准元素。三数中值法指的是,在待排序数列中,取出首、尾、中三个位置的数,取其中的中位数作为基准元素。随机法则是随机选择待排序列表中的一个元素作为基准元素。
2. 分割点的选定
分割点的选定是快排的关键之一。选取分割点的过程也就是 partition 函数的实现。一般来说,我们可以使用两个指针,一个指向起始位置,一个指向末尾位置,然后对比大小,交换位置。在实现 partition 函数时候,有以下三种实现方式:
(1)左右指针同时从头开始查找。左指针向右扫描,当扫描到比基准数大的时候退出循环,接着右指针向左扫描,扫到比基准数小的退出,然后交换两个数在继续进行以上操作,直到左指针大于右指针。
(2)左右指针同时从尾部开始查找。右指针向左扫描直到扫描到比基准数小的为止,左指针接着向右扫描直到扫描到比基准数大的为止,然后交换两个数继续以上操作,直到左指针大于右指针。
(3)单向查找。从小于基准数的部分开始,向后扫描直到大于基准数,然后将他们进行交换,直到完成整个数组的遍历。
3. 递归结束条件的制定
快速排序属于递归算法,递归结束条件必须明确。在递归中,每个子数组都会接受按照 pivot 元素划分成了两个区域的数据,并分别进行排序。当左指针 < 右指针 时,递归继续,否则结束。
微信扫一扫,领取最新备考资料