vlambda博客
学习文章列表

秒懂算法 | 快速排序算法中的分治思想

讲解快速排序的分治递归算法。


快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序,其基本思想是通过一趟扫描将待排序的元素分割成独立的三个序列:第一个序列中所有元素均不大于基准元素、第二个序列是基准元素、第三个序列中所有元素均大于基准元素。由于第二个序列已经处于正确位置,因此需要再按此方法对第一个序列和第三个序列分别进行排序,整个排序过程可以递归进行,最终可使整个序列变成有序序列。


01

问题分析——分与治的方法


(1) 分解:快速排序的分解是基于基准元素的,所以首先要选定一个元素作为基准元素,然后以选定的基准元素为标杆,将其他元素分成两部分,一部分不大于基准元素,另一部分大于基准元素。

(2) 基准元素的选取:从待排序序列中选取的基准元素是决定算法性能的关键。基准元素的选取应该遵循平衡子问题的原则,即使得划分后的两个子序列的长度尽量相同。基准元素的选择方法有很多种,常用的有以下5种。

① 取第一个元素。即以待排序序列的首元素作为基准元素。

② 取最后一个元素。即以待排序序列的尾元素作为基准元素。

③ 取位于中间位置的元素。即以待排序序列的中间位置的元素作为基准元素。

④ “三者取中的规则”。即在待排序序列中,将该序列的第一个元素、最后一个元素和中间位置的元素进行比较,取三者之中值作为基准元素。

⑤ 随机取一个元素作为基准元素。

(3) 治理:递归不大于基准元素的子序列,然后再递归大于基准元素的子序列,这样不大于基准元素的子序列和大于基准元素的子序列都有序了。基准元素位于正确的位置,整个序列就都有序了,完成了排序的目的。边界条件为子序列且为空或只有1个元素。


02

算法设计

将待排序的n个元素放到列表lis中,用left和right记录子问题在lis中的位置及规模,基准元素记为pivot。首先定义一个partition()函数完成分解任务,然后采用递归方法完成子问题的排序。

在划分过程中,选取待排序元素的第一个元素作为基准元素,然后从左向右、从右向左两个方向轮流找出位置不正确的元素,将其交换位置。该过程一直持续到所有元素都比较结束。最后将基准元素放到正确的位置。

划分操作伪码描述如下:

秒懂算法 | 快速排序算法中的分治思想

秒懂算法 | 快速排序算法中的分治思想

基于划分的结果,快速排序递归左边的子序列lis[left:j-1],递归右边的子序列lis[j+1:right],伪码描述如下: 
算法:quickSort(lis,left,right)
输入:待排序序列、子问题的边界leftright
输出:有序序列lis
if left < right: 
    j ← partition1(lis,left,right)
    quickSort(arr, left, j-1)
    quickSort(arr, j+1, right)


03

实例构造


给定序列23,15,10,50,93,12,2,68,采用快速排序方法将其升序排列。

(1) 初始序列,如图3-31所示,23为基准元素,i=0,j=8。

秒懂算法 | 快速排序算法中的分治思想

■ 图3-31划分初始状态


(2) 从左向右扫描元素:先推动i指针,后比较,若i指向的元素小于或等于基准元素,则继续推动指针、再比较,直到i指向的元素比基准元素大为止,此时i指向的元素位置不正确,应该在右子序列中,所以应该调走,如图3-32所示。

秒懂算法 | 快速排序算法中的分治思想

■ 图3-32i指针停止状态


(3) 从右向左扫描元素:先推动j指针,后比较,若j指向的元素大于基准元素,则继续推动指针、比较,直到j指向的元素比基准元素小或相等为止,此时j指向的元素位置不正确,应该在左子序列中,所以应该调走,如图3-33所示。

秒懂算法 | 快速排序算法中的分治思想

■ 图3-33j指针停止状态


(4) 交换i指向的元素和j指向的元素,如图3-34所示。

秒懂算法 | 快速排序算法中的分治思想

■ 图3-34元素交换后的状态


(5) 由于i<j,所以继续循环,推动i指针,直到i指向的元素大于基准元素;推动j指针,直到j指向的元素小于或等于基准元素,如图3-35所示。

秒懂算法 | 快速排序算法中的分治思想

■ 图3-35i指针和j指针第二次扫描停止的状态


(6) 此时i>j,跳出while(True)循环,将基准元素与j指向的元素交换位置,则j便是基准元素的位置,如图3-36所示。

秒懂算法 | 快速排序算法中的分治思想

■ 图3-36基准元素放到正确位置的状态


(7) 递归处理左子序列12,15,10,递归处理右子序列93,50,62,68。递归结束的时候,左右子序列均有序了,整个序列也都有序了,如图3-37所示。

秒懂算法 | 快速排序算法中的分治思想

■ 图3-37左右子问题递归结束的状态


实例讲解

算法设计与分析(Python版)

秒懂算法 | 快速排序算法中的分治思想

精彩回顾

秒懂算法


下期预告

秒懂算法

动态规划算法的基本思想

矩阵连乘问题

0-1背包问题的动态规划改进算法——跳跃点算法

子集树模型——0-1背包问题的回溯算法

满m叉树模型——图的m可着色问题的回溯算法

排列树模型——旅行商问题的分支限界法

最大网络流的增广路算法

蒙特卡罗算法



02

参考书籍

秒懂算法 | 快速排序算法中的分治思想

《算法设计与分析》

ISBN:9787302570721

定价:59.90元

秒懂算法 | 快速排序算法中的分治思想



03

精彩推荐








秒懂算法 | 快速排序算法中的分治思想