一种递归实现的快速排序精讲

简介:

快速排序是个“综合素质”较好的排序,比如javaSE中的Arrays.sort()实现原理,也是用的是快速排序思想。下面就看看一种快速排序的递归实现方式

要点:

1,分治思想,把问题划分成可以与本问题处理方式相同的若干子问题,使用递归来解决。

如排序问题,可以

(1)把原数组A[p,q](原问题)划分成三个部分 :较小部分A[p,m-1]  中间元素x=A[m]  较大部分A[m+1,q]

这样把部分当做一个整体看待是有序的A[p,m-1] <  A[m]  <  A[m+1,q]

(2)同理,无论是较小部分还是较大部分都可以继续按(1)操作继续划分得更细,直到每个部分的元素

被划分得只有单个元素,原数组之间每个元素就有序了

特征:

1,快速排序是原址排序,子问题解决的时候,不需要整体再次合并排序结果

2,递归调用在非常的数据的时候可能会发生栈溢出(递归深度太大)

难点:

如何划分成相对有序的三个部分?

思路:

(1)在原数组的某个好识别的位置取出一个数做中间元素x(部分2)。(一般取数组末元素,如x=A[q])

(2)采取一个位置变量i来左划分界线,保证i上和i的左边都是小部分元素(部分1)

(i的初始位置应当在问题范围的前一个位置,因为此时还没开始划分)

(3)除了x元素,循环取出原数组中的每个元素A[j]与x做比较

遇到不大于中间元素x要收集到界线上:

原界线i右移一个,此时i指向的元素是不确定性质的元素,

不确定元素和已经遇到的确定的小部分元素A[j]交换位置。(不确定换确定)

遇到大于中间元素的,界线i不动,j继续向右扫描(i和j之间的定是大部分元素,部分3)

(4)让中间元素交换到真正位置。一遍循环后,可以分出 小部分 和 大部分,

此时只要在界线的右一个(即大部分中的某个元素)与中间元素交换即可让划分的三个部分满足排序关系。

图片描述:

代码描述:

void
quicklySort(int *arr , int start , int last){

int mid;

if(start<last){

mid = partition(arr, start, last);//划分子问题

quicklySort(arr, start , mid-1);//解决左边部分

quicklySort(arr, mid+1, last);//解决右边部分

}

}

int
partition(int *arr, int start, int last){

int x = arr[last];//取本段数组最后一个元素,稍后使其成为划分好的中间元素

int i=0,j=0;

i=start-1;//使用i来控制两个部分的分界,初始值在子问题范围的前一个

for(j=start;j<= last-1; j++){

if(arr[j]<= x){//如果j走过的值是属于较小部分

++i;//较小部分分界线多收集一个空间

swap(arr[i],arr[j]);//把属于较小部分的值交换到这个空间(原址排序)

}

//如果是较大部分,让j继续向后滑行

}

swap(arr[i+1],arr[last]);//把选择参照的值交换到小部分和大部分之间

return i+1;//返回划分好的中间位置

}

时间: 2024-10-12 20:50:48

一种递归实现的快速排序精讲的相关文章

玩转算法系列--图论精讲 面试升职必备(Java版)

第1章 和bobo老师一起,玩转图论算法欢迎大家来到我的新课程:<玩转图论算法>.在这个课程中,我们将一起完整学习图论领域的经典算法,培养大家的图论建模能力.通过这个课程的学习,你将能够真正地,玩转图论算法:) 第2章 图的基本表示千里之行,驶于足下.解决任何有一个图论算法问题,首先需要用基本的数据结构来表示图.在这一章,我们就将探索图的基本表示问题,学习邻接矩阵和邻接表,进而,也让同学们熟悉这个课程的整体代码风格. 第3章 图的深度优先遍历任何一种数据结构,都需要进行遍历.图也不例外.通过深

第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的mapping映射管理

第三百六十四节,Python分布式爬虫打造搜索引擎Scrapy精讲-elasticsearch(搜索引擎)的mapping映射管理 1.映射(mapping)介绍 映射:创建索引的时候,可以预先定义字段的类型以及相关属性elasticsearch会根据json源数据的基础类型猜测你想要的字段映射,将输入的数据转换成可搜索的索引项,mapping就是我们自己定义的字段数据类型,同时告诉elasticsearch如何索引数据以及是否可以被搜索 作用:会让索引建立的更加细致和完善 类型:静态映射和动态

std::sort 学习:一种递归分治方法

// std::sort 学习:一种递归分治方法 今天看了看 stl 的 std::sort 的代码,众所周知,这个函数是在快速排序递归太深的时候使用堆排序防止过度退化,但是今天说的不是这个.我们只看快速排序的部分. 我们一般实现快速排序大概是这样的(本王随意写了个用下标当参数的排序函数,领会意思即可). void quick_sort(int first, int last) // 某个数组的 [first, last) {  if ((last - first) > 1) {  int mi

iOS开发——语法篇OC篇&amp;高级语法精讲二

Objective高级语法精讲二 Objective-C是基于C语言加入了面向对象特性和消息转发机制的动态语言,这意味着它不仅需要一个编译器,还需要Runtime系统来动态创建类和对象,进行消息发送和转发.下面通过分析Apple开源的Runtime代码(我使用的版本是objc4-646.tar)来深入理解Objective-C的Runtime机制. Runtime数据结构 在Objective-C中,使用[receiver message]语法并不会马上执行receiver对象的message方

系统分析师教程知识点精讲之标准化知识

软考系统分析师在2017上半年开考,整理了一些系统分析师教程知识点精讲. 标准化知识 按照ISO/IEC9126,软件质量模型包括6个质量特性和21个质量子特性: SW-CMM软件采办能力成熟度模型:关注的是软件购买者的软件能力成熟度: 而CMM关注的是软件系统承包者或开发商的软件能力成熟度. ISO/IEC 15504提供了一个软件过程评估的框架. 我国标准与国际标准对应关系有4种: 等同采用:idt 修改采用:mod 等效采用:eqv 非等效采用:neq 一旦国家标准出台,对应的行业标准.地

Hibernate入门精讲

学习Hibernate ,我们首先要知道为什么要学习它?它有什么好处?也就是我们为什么要学习框架技术? 还要知道    什么是Hibernate?    为什么要使用Hibernate?    Hibernate的配置文件的作用是什么?          Hibernate映射文件的作用是什么?     Hibernate持久化对象的状态有哪些? 现在我先上面的问题解决了. 一.我们为什么要学习框架技术? 1.框架技术有哪些? 在Java开发中,我们经常使用Struts.Hibernate和Sp

Keepalived原理与实战精讲

什么是Keepalived呢,keepalived观其名可知,保持存活,在网络里面就是保持在线了,也就是所谓的高可用或热备,用来防止单点故障(单点故障是指一旦某一点出现故障就会导致整个系统架构的不可用)的发生,那说到keepalived时不得不说的一个协议就是VRRP协议,可以说这个协议就是keepalived实现的基础,那么首先我们来看看VRRP协议 注:搞运维的要有足够的耐心哦,不理解协议就很难透彻的掌握keepalived的了 一,VRRP协议VRRP协议学过网络的朋友都知道,网络在设计的

第三百五十八节,Python分布式爬虫打造搜索引擎Scrapy精讲—将bloomfilter(布隆过滤器)集成到scrapy-redis中

第三百五十八节,Python分布式爬虫打造搜索引擎Scrapy精讲-将bloomfilter(布隆过滤器)集成到scrapy-redis中,判断URL是否重复 布隆过滤器(Bloom Filter)详解 基本概念 如果想判断一个元素是不是在一个集合里,一般想到的是将所有元素保存起来,然后通过比较确定.链表,树等等数据结构都是这种思路. 但是随着集合中元素的增加,我们需要的存储空间越来越大,检索速度也越来越慢.不过世界上还有一种叫作散列表(又叫哈希表,Hash table)的数据结构.它可以通过一

【C++自我精讲】基础系列六 PIMPL模式

0 前言 很实用的一种基础模式. 1 PIMPL解释 PIMPL(Private Implementation 或 Pointer to Implementation)是通过一个私有的成员指针,将指针所指向的类的内部实现数据进行隐藏. 2 PIMPL优点 举例: //x.h class X { public: void Fun(); private: int i; //add int i; }; //c.h #include <x.h> class C { public: void Fun()