《算法之美》---快速排序(随机快速排序)

考点总结 软件构造的多维度视图By phases: build- and run-time viewsBy dynamics: moment and period viewsBy levels: code and component views内部/外部的质量指标External quality factors: qualities such as speed or ease of use, whose p... 阅读详情

快速排序是对冒泡排序的一种改进,它使用分治的思想,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录循环进行排序,以达到整个序列有序的状态。

 

快速排序是C.A.R Hoare在1962年提出的,显然,它是一种分治算法,并且是原地排序算法。快速排序可分为四个步骤:

1)选择杠杆点:在待排序的序列中按照某种方式选取一个元素作为划分的杠杆点。

2)分解:以杠杆点为界,将序列分为两个子序列,其中一个子序列里的所有元素小于等于杠杆点,另一个子序列里的所有元素大于杠杆点。

3)治之:递归对两个子序列进行快速排序。

4)合并:将排好序的两个子序列合并成大序列。

 

快速排序的时间成本取决于分解这一步,分解的好坏将对整个算法的效率产生决定性影响。但分解的好坏取决于杠杆点的选择。下面是标准的序列分解算法:

PARTITION(A, m, n)             //A[m...n]为一个序列

        x<--A[m]                  //A[m]为我们选择的杠杆点

        i<--m

        for j<--m+1   to  n  do

                  if A[j]<=x then

                           i<--i+1

                           Exchange A[i] <--> A[j]

        Exchange A[m] <--> A[i]

        return i;

 

上述算法将子序列A[m…n]以A[m]为界分解为两个子序列:A[m…i-1]和A[i+1…n]。在每一次for循环中,A[m…i]里面的元素都小于等于杠杆点x,A[i+1…j]里面的元素都大于杠杆点x,而A[j+1…n]里面的元素是尚未分解的子序列里的元素。

有了分解算法之后,整个快速排序算法如下:

QUICKSORT(A, p, r)

        if p<r then

                  q <-- PARTITION(A, p, r)

                  QUICKSORT(A, p, q-1);

                  QUICKSORT(A, q+1, r);

 

程序的初始调用为QUICKSORT(A, 1, n)。

 

快速排序最坏情况下时间复杂度是Θ(n2),最好情况下和平均情况下都是Θ(nlogn)。

 

快速排序分解出的子序列是否为空取决于杠杆点与其他元素的相对关系,因此,在使用快速排序的时候,要想保证算法的时间复杂度不被输入序列有意地操控,我们在选择杠杆点的时候就不能是确定性的。如果每次都是随机选择一个元素作为杠杆点,则无论对手进行多少次实验也不能得出任何肯定的结论,自然也就不能有针对性的进行输入数据次序的安排来使我们快排算法总是处于最坏时间复杂度下。


随机化快速排序算法模板如下:

/*

函数名:     quick_sort

功能:       快速排序辅助过程

*/

template <typename T>

void quick_sort (T data[],int frist,int last)

{

        int lower=frist+1;

        int upper=last;

        int t=rand()%(last-frist)+frist;

        std::swap(data[frist], data[t]);

        T& bound=data[frist];

        while (lower<=upper)

        {

                  while (data[lower]<bound)

                  {

                           ++lower;

                  }

                  while (bound<data[upper])

                  {

                           --upper;

                  }

                  if (lower<upper)

                  {

                           std::swap(data[lower], data[upper]);

                           ++lower;

                           --upper;

                  }

                  else

                           ++lower;

        }

        std::swap(data[upper], data[frist]);

        if (frist<upper-1)

                  quick_sort(data, frist, upper-1);

        if (upper+1<last)

                  quick_sort(data, upper+1, last);

}

 

/*

函数名:     QuickSort

功能:       快速排序

模板参数说明:T必须支持小于操作

参数说明:   data待排序数组, size待排序数组大小

前置条件:   data!=NULL, size>0

后置条件:   data按排列

用法:

#include <algorithm>

#include <stdlib.h>

#include <time.h>

int arr[]={10,9,8,4,5,7,6,3,1,4};

QuickSort(arr, 10);

*/

template <typename T>

void QuickSort (T data[],int size)

{

        int i, max;

        if (size<2)

                  return;

        for (i=1, max=0; i<size; ++i)

        {

                  if (data[max]<data[i])

                           max=i;

        }

        std::swap(data[size-1], data[max]);

        srand(time(0));

        quick_sort(data, 0, size-2);

}

 

 

 

/*

函数名:     quick_sort

功能:       快速排序辅助过程

*/

template <typename T, typename Func>

void quick_sort (T data[],int frist,int last, Func& f)

{

        int lower=frist+1;

        int upper=last;

        int t=rand()%(last-frist)+frist;

        std::swap(data[frist], data[t]);

        T& bound=data[frist];

        while (lower<=upper)

        {

                  while (f(data[lower],bound))

                           ++lower;

                  while (f(bound,data[upper]))

                           --upper;

                  if (lower<upper)

                  {

                           std::swap(data[lower], data[upper]);

                           ++lower;

                           --upper;

                  }

                  else

                           ++lower;

        }

        std::swap(data[upper], data[frist]);

        if (frist<upper-1)

                  quick_sort(data, frist, upper-1, f);

        if (upper+1<last)

                  quick_sort(data, upper+1, last, f);

}

 

/*

函数名:     QuickSort

功能:       快速排序

模板参数说明:T元素类型,Func函数对象或指针

参数说明:   data待排序数组, size待排序数组大小,函数对象或指针

前置条件:   data!=NULL, size>0

后置条件:   data按排列

用法:

#include <algorithm>

#include <stdlib.h>

#include <time.h>

bool cmp(int a, int b)

{ return a<b; }

int arr[]={10,9,8,4,5,7,6,3,1,4};

QuickSort(arr, 10, cmp);

*/

template <typename T, typename Func>

void QuickSort (T data[],int size, Func f)

{

        int i, max;

        if (size<2)

                  return;

        for (i=1, max=0; i<size; ++i)

        {

                  if (f(data[max],data[i]))

                           max=i;

        }

        std::swap(data[size-1], data[max]);

        srand(time(0));

        quick_sort(data, 0, size-2, f);

}

 

C++ 快速排序&随机快速排序 学习记录 C++ 快速排序 记录 都是网上的资源,侵删。 今天学习了快速排序算法,它们的时间以及空间复杂度表格: 快速排序(Quicksort)是对冒泡排序的一种改进。 快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进... 阅读详情

相关推荐

数据结构与算法:随机快速排序及随机快速算法

随机快速排序及随机快速算法

2402_89326161的博客 936

关于基于比较的排序算法,时间复杂度“最坏”下界o(nlogn)与“最优”下界o(n)说明

前言            之前在查找基于比较排序算法的时间复杂度时发现,好多博主对“最坏”下界与“最优”下界没有分清,而是默认的把时间复杂度o(nlogn)当成了“最优”下界。这样很是误导大家,影响很不好。所以特此写一篇说明文章,能让大家理解得更透彻。 下界                       所谓“下界”, 顾名思义就是对于一个长度为n的序列所需要的最少比较次数。 最优下界 ...

WFL_Tesla的博客 1万+

随机选择策略的快速排序

/* Subject:计算机算法设计与分析 Title:2.8.2随机选择策略的快速排序 Coder:Hao Class:计科0906 Num:0304090614 Date: Oct 2nd,2011 Programming Language:C++ */ #include using namespace std; //实现随机功能的函数 int Random(int p,int r)

翾昱 2601

快排的递归与非递归实现

最近面试问到的快排非递归和递归,整理了一下,方便自己review。

u013986213的博客 1813

半导体物理-Si晶体生长方向<2>

Si(硅)晶体的生长方向是一个重要的概念,尤其在半导体工业中。这个概念涉及到晶体在生长过程中原子排列的方向,对晶体的性质和应用有重大影响。让我为您详细解释:理解Si晶体的生长方向对于半导体材料的研究和应用非常重要,它直接影响了最终器件的性能和制造工艺。在实际应用中,选择适当的生长方向可以优化器件性能,提高产品质量。

m0_37606066的博客 2991

arcgis插件 批量出图 按地块批量出图工具(动态文本、动态节点坐标表)

arcgis插件 批量出图 按地块批量出图工具。

坐听风雨 7065

【算法】随机快速排序和随机选择算法

学习一下更简洁的快排以及随机选择算法

Ahaooooooo的博客 1432

01|无代码开发 | 如何使用Zion实现导航网站制作

以上就是我制作导航网站的心得,分享给大家,作为一个小白想要独立搭建一个网站还是比较困难的,而在Zion不仅可以用可视化的方法进行搭建,甚至还可以一键发布,不用考虑服务器域名啥的问题,真是太方便了。

2301_76262110的博客 1390

Java算法OJ(7)随机快速排序

哈喽大家好吖,今儿给大家带来算法—随机快速排序相关知识点,废话不多说让我们开始。

2301_81073317的博客 3241

Playwright实战:打造绕过全维度前端反爬的无头浏览器爬虫(2026实战版)

Playwright绕过前端反爬的核心是模拟真实:真实的设备指纹、真实的行为轨迹、真实的网络请求;2025年前端反爬的核心检测维度是设备指纹+行为轨迹+网络请求,三者缺一不可;实战中需重点关注WebGL/Canvas指纹模拟、行为随机性、请求头完整性,这是绕过反爬的关键;性能优化需以“不触发反爬”为前提,优先选择浏览器复用、资源拦截,而非无限制并发。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 2094

31.XAPP1052乱序分析及处理

目录 1.XAPP1052乱序分析 2.XAPP1052乱序处理 2.1乱序处理方法选择 2.2 XAPP1052乱序处理代码详解 3.XAPP1052乱序处理后的波形分析 3.1发送引擎 3.2接收引擎 4.XAPP1052乱序处理后的带宽测试 5.下期内容 1.XAPP1052乱序分析 首先先给大家讲解下什么是PCIe的乱序。在PCIe系统中,乱序就是主机发送的TLP序列ID为1、2、3、4到从机,从机接收到的可能不是1、2、3、4。主机和从机如果都不解决乱序的问题,就会导致从机接

一个早起的程序员 1707

排序算法——随机快速排序

引言 随机快排是一个非常有意思的排序排序算法,它的算法思想用到了如递归、荷兰国旗问题等诸多元素,还意外的引入了随机性的概念。 以下将逐步总结三个版本的快速排序,由浅入深总结快速排序的经典实现过程。 荷兰国旗问题参考:《荷兰国旗问题》 一、快速排序1.0 在荷兰国旗问题中,我们通过简单的逻辑可以将一个数组分为两个区域或三个区域,但往往需要在题目之初给定一个 target 作为目标数以此划分。 而在快速排序算法中,这个 target 选为排序范围上的最右边的数——arr[R],我们以 R 上的数为

Morty的技术乐园 6482

YOLOv10改进策略【Neck】| arXiv 2025 分层多头注意力HMHA 子空间拆分提多样 + 通道重排降冗余,强化目标检测精度

HMHA(Hierarchical Multi-Head Attention,分层多头注意力)旨在解决传统多头注意力(MHA)在图像恢复任务中的核心缺陷——特征冗余。传统MHA将通道均匀拆分给各个头,导致不同头学习的子空间信息相似,进而出现多头关注同一区域、忽略退化区域修复的问题,限制了模型的特征表达能力。HMHA通过“分层子空间拆分+通道重排序”策略,让每个头学习差异化、互补的上下文特征,从根源上缓解冗余,提升图像恢复任务中对复杂退化场景的特征捕捉能力。

Limiiiing的博客 103

刷题日志(4)——随机快速排序与随机选择算法

假设存在一片存储<=x的区域,一开始为空,变量a 记录了该区域的边界,当nums[i]<=x,将该元素放到该区域,同时,边界扩大,i++,当nums[i]>x时,区域不动i++,当遍历完成即完成目标。思路:定义两片区域,其边界分别用变量 a,b来存储,如果nums[i]<x,则将该元素放入小于x的区域,并且向右扩,i++,如果nums[i]=x,则i++,而若未命中,出现在>x区域,则<=x区域不管,再次在>x区域选择新x进行划分,之后同理直至找到第K大的数。),遍历完成后即达成目标。经典随机快排的缺点?

qq_51914226的博客 1549

lammps案例:聚乙烯和石墨烯界面pull out模拟

大家好,我是小马老师。 本文介绍lammps模拟计算界面结合力的一个案例。 本案例参考论文《The interfacial mechanical properties of functionalized graphene- polymer nanocomposites》,对论文作者表示感谢。 模型共分2层,上层为聚乙烯模型,下次为单层石墨烯,模拟过程共分3部分:建模、弛豫、拉伸。 (1)建模 使用MS建立聚乙烯和石墨烯模型,具体方法可参考之前的推文,使用build layer方法建立聚乙烯和石墨烯组合模型,

lammps_jiayou的博客 3494

微信小程序 - 最新详细实现用户保存下载视频到手机相册,将视频临时路径、在线播放地址(网络路径)URL存储到手机,弹出访问手机相册权限询问,支持视频格式mp4、avi、mov、wmv、flv、webm

微信小程序,视频,手机相册,保存,另存为,小程序保存到相册权限,writePhotosAlbum,一键保存视频到手机相册功能(视频来源为链接),第一次要获取用户授权,授权使用相册权限,小程序视频下载,如何把视频下载到相册,下载一个视频到本地相册,显示下载进度,可取消下载,视频下载到本地,微信小程序视频如何下载,保存视频到相机,页面播放视频并下载到本地,安卓系统,苹果ios保存到相册报错,权限拒绝后打不开,添加相册授权弹框拒绝后再也出不来了,实现保存视频到手机相册功能,将mp4在线视频下载并存储到用户的手机中

🏆 前端领域优质创作者 7623

[算法]快速排序与随机快速排序

与归并排序一样,快速排序也运用了分治策略,而随机快速排序是对快速排序的一种优化。

hula_hula_的博客 1635

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

快速排序之随机快排

随机快排之C语言 问题: 快速排序大家应该都比较了解了,利用分治法的思想,将原有的数据分成两个部分,递归分治排序。大致有 4 个步骤: 首先设定一个分界值,通过该分界值将数组分成左右两部分。 将大于或等于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边。此时,左边部分中各元素都小于或等于分界值,而右边部分中各元素都大于或等于分界值。 然后,左边和右边的数据可以独立排序。对于左侧的数组数据,又可以取一个分界值,将该部分数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数组数据也可以

Indomite的博客 2451

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

随机快速排序(简述和证明)

快速排序算法复习,随即快速排序算法介绍,证明

LuciferXD的博客 3108

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

随机快速排序算法(C语言)

随机快速排序(C语言) 分治法基本思想 将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。递归的解决这些子问题,然后将各个子问题的解合并得到原问题的解。 快速排序 原链接:https://blog.youkuaiyun.com/haelang/article/details/44496387 快速排序用到了分治思想,同样的还有归并排序。乍看起来快速排序和归并排序非常相似,都是将问题变小,先排序子串,最后合并。不同的是快速排序在划分子问题的时候经过多一步处理,将划分的两组数据划分为一大

Weightlessly的博客 3492

快速排序及随机快速排序算法(附完整代码)

快速排序算法是基于分治策略的另一个排序算法,思想是输入的子数组a[p:r],按以下三个步骤进行排序: 分解(Divide):以a[p]为基准元素将a[p:r]划分成3段a[p:q-1] 、a[q]、a[q+1:r],使a[p:q-1]中任何一个元素小于等于a[p],而a[q+1:r]中任何一个元素大于等于a[q]。下标q在划分过程中确定。 递归求解(Conquer):通过递归调用快速排序算法,分别对a[p:q-1]和a[q+1:r]进行排序 合并(Merge):由于a[p:q-1]和a[q+1:

weixin_44469806的博客 2341

随机快速排序+随机选择算法

注:关于c语言中随机选择的函数rand需注意:rand()%(n)就会随机选取0~n-其头文件是#include(c++中也有自己的随机选择函数库)

2301_80275822的博客 1303

快速排序 与 随机快速排序 算法分析

快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。 快速排序的优点: (1)原址排序,空间复杂度较小。 (2)虽然最坏情况下(有序数组)

hustyangju的足迹 4119

经典快速排序与随机快速排序

文章目录一、经典快速排序(一)、经典快速排序的实现理论(二)、经典快速排序的代码实现(Java)(三)、经典快速排序的时间复杂度二、随机快速排序(一)随机快速排序的实现理论(二)随机快速排序的代码实现(Java)(三)、随机快速排序的时间复杂度 一、经典快速排序 (一)、经典快速排序的实现理论 经典快速排序是用数组的最后一个数(这里记为 x )进行划分。也就是 &amp;lt;x、=x、&amp;gt;x。 有...

liyanan的博客 3037
上一篇: 《算法之美》---堆排序
下一篇: 《算法之美》---次序选择问题
ACE1985
博客等级 码龄17年 1307粉丝 308原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值