上篇博客我们主要聊了比较高效的归并排序算法,本篇博客我们就来介绍另一种高效的排序算法:快速排序。快速排序的思想与归并排序类似,都是采用分而治之的方式进行排序的。快速排序的思想主要是取出无序序列中第一个值,然后通过比较将比该值小的元素放到该值的前方,将比该值大的元素放在该值的后方。这样一来该值前方的数据都要比该值小,该值后方的数据都要比该值大。然后再次对前半部分和后边半部分无序的数列进行上述操作,这样不断的操作,无序的序列的规模不断被缩小。等问题的规模被缩小到一定程度后,我们的序列就变的有序了。

之前我们说过,当一个问题可以被分成一些相同的子问题时,我们就可以使用递归来操作。所以在快速排序的过程中,我们是通过递归的方式将问题规模逐渐减小,知道序列为序为止。本篇博客将会给出这一过程,根据示意图,给出相应的代码实现。

一、将无序数组进行拆分

在本篇博客,我们先聊一聊如果将大的问题拆分成一些相同的子问题。我们需要对需要排序的数组进行拆分,从无序序列中取出一个值,然后通过比较,将比该值大的放在该值的后方,比该值小的,放在该值的前方。本部分,我们将给出相应的示意图以及代码实现。

1.拆分示意图

下方就是我们上述过程的示意图。也是快速排序第一轮排序的过程。首先将无序数组中的第一个值进行暂存(temp = 62),经过下述步骤,我们会将那些比62小的元素放到62的前面,比62大的元素放到后边。low负责遍历前半部分,将前半部分大于62的值放到后边,而high负责遍历后半部分,将后半部分小于62的值放前边。具体步骤如下所示。

  

2.代码实现

根据上述示意图,我们可以给出相应的代码实现。如果上述的示意图理解了,看下方代码的实现是比较简单的。partition()函数就负责将一个无序的数组转变的以第一个值为准,较小的值放在该值的前边,较大的放在该值的后边。如下所示。

  

 

二、快速排序

实现完拆分方法后,我们就该实现快速排序的代码了。上面的代码是快排的核心,接下来做的事情是调用上述的函数将无序数组进行拆分,然后再调用上述函数将前后无序的小数组进行拆分,依次执行下去,我们的数组就是有序的了。其实就是一个递归的过程。下方的quickSort()就是这个过程。首先将无需数组调用partition()方法进行拆分,然后再次调用quickSort()方法执行前半部分,同样的调用quickSort()方法执行后半部分。代码如下所示。

  

定义完快速排序的核心方法后,接下来就是使用了。下方的QuickSort就是相应的快速排序类,QuickSort还是要遵循SortType这个排序协议的,而sort()方法则是该协议中定义的对外调用的接口。具体代码如下所示。

  

三、测试用例

用我QuickSort类遵循了SortType方法,我们依然可以使用之前的测试用例。下方就是我们的测试用例,与之前使用的一直,只不过需要将QuickSort这个类的对象传给我们的测试函数即可,如下所示:

  

本篇博客快速排序的运行结果如下:

  

本篇博客对堆排序的介绍就先到这儿,下篇博客我们将会介绍“基数排序”的详细内容。本篇博客的相关代码依然会在github上进行分享,下方是github分享地址,如下所示:

github代码分享地址:https://github.com/lizelu/DataStruct-Swift/tree/master/AllKindsOfSort

算法与数据结构(十六) 快速排序(Swift 3.0版)的更多相关文章

  1. 算法与数据结构(十五) 归并排序(Swift 3.0版)

    上篇博客我们主要聊了堆排序的相关内容,本篇博客,我们就来聊一下归并排序的相关内容.归并排序主要用了分治法的思想,在归并排序中,将我们需要排序的数组进行拆分,将其拆分的足够小.当拆分的数组中只有一个元素 ...

  2. 算法与数据结构(十四) 堆排序 (Swift 3.0版)

    上篇博客主要讲了冒泡排序.插入排序.希尔排序以及选择排序.本篇博客就来讲一下堆排序(Heap Sort).看到堆排序这个名字我们就应该知道这种排序方式的特点,就是利用堆来讲我们的序列进行排序.&quo ...

  3. 算法与数据结构(十二) 散列(哈希)表的创建与查找(Swift版)

    散列表又称为哈希表(Hash Table), 是为了方便查找而生的数据结构.关于散列的表的解释,我想引用维基百科上的解释,如下所示: 散列表(Hash table,也叫哈希表),是根据键(Key)而直 ...

  4. 算法与数据结构(十) 二叉排序树的查找、插入与删除(Swift版)

    在上一篇博客中,我们主要介绍了四种查找的方法,包括顺序查找.折半查找.插入查找以及Fibonacci查找.上面这几种查找方式都是基于线性表的查找方式,今天博客中我们来介绍一下基于二叉树结构的查找,也就 ...

  5. 算法与数据结构(十七) 基数排序(Swift 3.0版)

    前面几篇博客我们已经陆陆续续的为大家介绍了7种排序方式,今天博客的主题依然与排序算法相关.今天这篇博客就来聊聊基数排序,基数排序算法是不稳定的排序算法,在排序数字较小的情况下,基数排序算法的效率还是比 ...

  6. 浅谈算法和数据结构: 十 平衡查找树之B树

    前面讲解了平衡查找树中的2-3树以及其实现红黑树.2-3树种,一个节点最多有2个key,而红黑树则使用染色的方式来标识这两个key. 维基百科对B树的定义为“在计算机科学中,B树(B-tree)是一种 ...

  7. 转 浅谈算法和数据结构: 十 平衡查找树之B树

    前面讲解了平衡查找树中的2-3树以及其实现红黑树.2-3树种,一个节点最多有2个key,而红黑树则使用染色的方式来标识这两个key. 维基百科对B树的定义为"在计算机科学中,B树(B-tre ...

  8. JAVA常见算法题(二十六)

    package com.xiaowu.demo; import java.util.Scanner; /** * Java实现将阿拉伯数字转为汉字 * * @author WQ * */ public ...

  9. 每日算法之二十六:Substring with Concatenation of All Words

    变相的字符串匹配 给定一个字符串,然后再给定一组同样长度的单词列表,要求在字符串中查找满足下面条件的起始位置: 1)从这个位置開始包括单词列表中全部的单词.且每一个单词仅且必须出现一次. 2)在出现的 ...

随机推荐

  1. iOS开发系列--Swift语言

    概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在 ...

  2. Hello Web API系列教程——Web API与国际化

    软件国际化是在软件设计和文档开发过程中,使得功能和代码设计能处理多种语言和文化习俗,在创建不同语言版本时,不需要重新设计源程序代码的软件工程方法.这在很多成熟的软件开发平台中非常常见.对于.net开发 ...

  3. 关于Vue.js 2.0 的 Vuex 2.0,你需要更新的知识库

    应用结构 实际上,Vuex 在怎么组织你的代码结构上面没有任何限制,相反,它强制规定了一系列高级的原则: 应用级的状态集中放在 store 中. 改变状态的唯一方式是提交mutations,这是个同步 ...

  4. iOS开发之Alamofire源码深度解析

    今天博客中的Alamofire源码的版本是以现在最新的3.4版本为例.上篇博客系统的对NSURLSession相关的东西进行了详细的解析,详情请看<详解NSURLSession>,为了就是 ...

  5. 【NLP】干货!Python NLTK结合stanford NLP工具包进行文本处理

    干货!详述Python NLTK下如何使用stanford NLP工具包 作者:白宁超 2016年11月6日19:28:43 摘要:NLTK是由宾夕法尼亚大学计算机和信息科学使用python语言实现的 ...

  6. [原] KVM 环境下MySQL性能对比

    KVM 环境下MySQL性能对比 标签(空格分隔): Cloud2.0 [TOC] 测试目的 对比MySQL在物理机和KVM环境下性能情况 压测标准 压测遵循单一变量原则,所有的对比都是只改变一个变量 ...

  7. HTTP API接口安全设计

    HTTP API接口安全设计 API接口调用方式 HTTP + 请求签名机制   HTTP + 参数签名机制 HTTPS + 访问令牌机制 有没有更好的方案? OAuth授权机制 OAuth2.0服务 ...

  8. SqlServer简单数据分页

    手边开发的后端项目一直以来都用的.NET MVC框架,访问数据库使用其自带的EF CodeFirst模式,写存储过程的能力都快退化了 闲来无事,自己写了条分页存储过程,网上类似的文章多的是,这里只列了 ...

  9. Linux实战教学笔记03:操作系统发展历程及系统版本选择

    标签(空格分隔): Linux实战教学笔记-陈思齐 第1章 Linux简介 1.1 什么是操作系统? 简单讲:操作系统就是一个人与计算机硬件的中介. 操作系统,英文名称Operating System ...

  10. DDD中的Unitwork与DomainEvent如何相容?(续)

    上篇中说到了面临的问题(传送门:DDD设计中的Unitwork与DomainEvent如何相容?),和当时实现的一个解决方案.在实际使用了几天后,有了新的思路,和@trunks 兄提出的观点类似.下面 ...