• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2020-05-08 10:55 Aet 隐藏边栏 |   抢沙发  24 
文章评分 5 次,平均分 5.0

简述

快速排序在每一轮挑选一个基准元素,并让其他比它大的元素移到数列一边,比它小的元素移到数列的另一边,从而把数列拆解成两个部分。

快速排序是从冒泡排序演变而来的。

快速排序也属于交换排序,通过元素之间的比较和交换位置来达到排序的目的。

为什么快速排序比较快?
因为它使用了分治法
【分治法:】将一个规模为N的问题,分成K个规模较小的子问题。这些子问题相互独立且与原问题性质相同。求出子问题的解,合并得到原问题的解。

复杂度

名称 最好 平均 最差 空间 稳定性
快速排序 nlog(n) nlog(n) n2 log(n)

双边循环理解

  1. 递归实现,寻找一个基准,将整个集合按基准分成两半去处理
    1. 快速排序是一种典型的分治算法
    2. 基本思想是将一个大的问题分解成若干个小问题分别解决,然后将它们的结果合并起来
    3. 可以理解为:通过递归的方式去达到分治的目的
  2. 在每一次递归调用中,会确定好一个基准,这个基准其实也代表着有一个元素被放置到正确的位置了

单边循环理解

  1. 同样是递归实现,同样需要找一个基准,将整个集合按基准分成两半去处理
  2. 一开始用arr[start]这个元素作为pivot,并且用start的下标值作为mark的初始值
    1. 于是,需要处理的元素,就需要从start+1开始
  3. 大循环中,从start+1的位置开始和所有元素挨个比较,任务就是找出比一开始记录的pivot(也就是arr[start])小的所有元素
    1. 在循环中每找到一个比pivot小的元素,就把mark向右移动一次,用移动后的位置和找到和元素的位置,进行值交换
    2. 这样,当循环结束,所有比pivot小的元素都挨个被存放在start的后面了
    3. 直到找不到比pivot更小的元素时,结束循环
  4. 循环结束后,序列中所有比pivot小的元素都位于start的右边,此时start存放的是pivot,而mark记录的是最后一个找到的比pivot小的元素
    1. 于是,将mark位置的元素和pivot进行值交换,mark位置左边的所有元素都是比它小的
  5. 这样,mark这个下标就是我们找到的基准,可以以mark为界限,把所有元素分成两半

实现

递归实现

双边循环法

选定一个基准元素,并指定两个指针left right,分别指向数列最左和最右的两个元素。

单边循环法

选定一个基准元素,并使用一个指针mark作为区域边界,只从数组的一边对元素进行遍历和交换。

非递归实现

通过栈的方式进行非递归实现快速排序。

算法导论

单边循环

划分思想,假设对数组A[p...r]划分,划分主元为A[q]:

  • 交换:首先将A[q]与A[r]交换,使得新的A[r]成为划分元素
  • 循环:维持循环不变式: A[p...smaller_next-1]始终小于A[r],A[smaller_next...current-1]始终大于A[r]。开始对A[current]进行判别
    • 若A[current]<A[r] 则交换 A[current]与 A[smaller_next], current右移(进行下一个元素的判断),smaller_next右移(维持不变式)
    • 若A[current]>=A[r], current右移(进行下一个元素的判断)
  • 时间复杂度 O(n)
  • 原地操作

  • begin : 待划分序列的起始迭代器(也可以是指向数组中某元素的指针)
  • end: 待划分序列的终止迭代器(也可以是指向数组中某元素的指针)
  • partition_iter: 指定划分元素的对应的迭代器(也可以是指向数组中某元素的指针)
  • compare: 一个可调用对象,可用于比较两个对象的小于比较,默认为std::less
  • 划分之后该划分元素值在序列中对应的新迭代器(也可以是指向数组中某元素的指针)

  • begin : 待排序序列的起始迭代器(也可以是指向数组中某元素的指针)
  • begin : 待排序序列的起始迭代器(也可以是指向数组中某元素的指针)
  • compare: 一个可调用对象,可用于比较两个对象的小于比较,默认为std::less
  • 最坏时间复杂度 O(n^2), 期望时间复杂度 O(nlgn)。它平均性能非常好,是实际排序应用中最好的选择
  • 原地排序

双边循环

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0 最后编辑于:2024-08-13
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享