一:什么是堆?

堆可视为  “以数组方式存储的一棵完全二叉树”

堆又分为最大堆和最小堆, 最大堆就是对于整个二叉树中的每一个节点都满足:节点的键值比其左右子节点的键值都要大,对应的最小堆则是:节点的键值比其左右子节点的键值都要小

二:堆排序的思路

    对于一个存储最大堆的数组arr(长度为size), 根节点arr[0]是所有节点中键值最大,将arr[0]和arr[size-1]的值交换,然后将除去arr[size-1]后的size-1个节点作为一个独立的二叉树,但是此时的这课新的树由于前面交换arr[0]和arr[size-1]的原因需要重新调整为堆。

    堆排序就是不断交换和调整的过程。所以我们先要解决两个问题

1.如何调整为最大堆(或者最小堆)

2.如何由一个无序的输入数组生成一个堆

具体代码如下:

调整:输入的参数为一个数组、堆大小和调整的位置(节点对应的数组下标,并假设该节点的左右子树已符合堆性质)

func maxHeapify<Elem: Comparable>(_ arr : inout [Elem], _ size: Int, _ pos: Int) {
    func swap(_ a: inout Elem, _ b: inout Elem) {
        let tmp = a
        a = b
        b = tmp
    }
   
    let l = 2*pos + 1
   
    let r = 2*pos + 2
   
    var index = pos
   
    if l < size && arr[l] > arr[index] {
        index = l
    }
   
    if r < size && arr[r] > arr[index] {
        index = r
    }
   
    if index != pos {
        swap(&arr[pos], &arr[index])
        maxHeapify(&arr, size, index)
    }
}

 

如何建立堆:输入的参数是一个无序的数组(一个从底向上的调整过程)

func buildMaxHeap<Elem: Comparable>(_ arr: inout [Elem]) {
    let bounce = arr.count/2 - 1
   
    for i in (0...bounce).reversed() {
        maxHeapify(&arr, arr.count, i)
    }
}

 

堆排序:

func heapSort<Elem: Comparable>(_ arr: inout [Elem]) {
    func swap(_ a: inout Elem, _ b: inout Elem) {
        let tmp = a
        a = b
        b = tmp
    }
       
    buildMaxHeap(&arr)   
   
    var size = arr.count
       
    while size > 1 {
        swap(&arr[0], &arr[size - 1])
        size = size - 1
        maxHeapify(&arr, size, 0)
    }
}

 

测试:

var intArray = [3, 8, 46, 38, 29, 15, 8]

print("before")

for elem in intArray {
    print("elem = \(elem)")
}

heapSort(&intArray)

print("after")

for elem in intArray {
    print("elem = \(elem)")
}

 

结果:

 

测试的环境:https://swiftlang.ng.bluemix.net/#/repl

堆排序(Swift版本)的更多相关文章

  1. 升级xcode8之后出现报错提示,提示swift版本问题

    最近Xcode升级了,出现了各种蛋疼的错误提示,今天遇到个导入框架出现了提示Swift版本的问题,具体如下: "Use Legacy Swift Language Version" ...

  2. 窥探Swift系列博客说明及其Swift版本间更新

    Swift到目前为止仍在更新,每次更新都会推陈出新,一些Swift旧版本中的东西在新Swift中并不适用,而且新版本的Swift会添加新的功能.到目前为止,Swift为2.1版本.去年翻译的Swift ...

  3. CocoaPods 更新慢&swift版本适配

    一.更新慢的问题 使用CocoaPods来添加第三方类库,无论是执行pod install还是pod update都卡在了Analyzing dependencies不动 原因在于当执行以上两个命令的 ...

  4. iOS swift版本无限滚动轮播图

    之前写过oc版本的无限滚动轮播图,现在来一个swift版本全部使用snapKit布局,数字还是pageConrrol样式可选 enum typeStyle: Int { case pageContro ...

  5. swift版本拼图游戏项目源码

    现学现做的第一个swift版本拼图游戏demo 常规模式,对换模式任你选择, 用到了花瓣的API,各种萌妹子~

  6. Swift版本UIWebView长按保存图片

    起因 最近需要做个IOS的壳子,用到长按保存图片的功能,发现百度出来的全是OC语法的例子,很多都不是全面,只能自己写一份Swift版本的,图片下面附上Github地址 效果图 Github地址:htt ...

  7. 查看MacOS中的Swift版本和SDK版本

    查看MacOS中的Swift版本和SDK版本 来源 https://juejin.im/post/5cde5a62f265da1bc55230e5 # 查看Swift版本 xcrun swift -v ...

  8. Swift 版本历史记录(关注)

    http://numbbbbb.gitbooks.io/-the-swift-programming-language-/content/chapter1/03_revision_history.ht ...

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

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

随机推荐

  1. js设计模式-桥接模式

    桥接模式定义:桥梁模式的用意是"将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化".这句话有三个关键词,也就是抽象化.实现化和 ...

  2. TensorFlow——分布式的TensorFlow运行环境

    当我们在大型的数据集上面进行深度学习的训练时,往往需要大量的运行资源,而且还要花费大量时间才能完成训练. 1.分布式TensorFlow的角色与原理 在分布式的TensorFlow中的角色分配如下: ...

  3. 开发vue插件并发布到npm包管理工具的流程

    1-10是开发流程,后面的是发布流程 1. 在Git里面…新建项目   2. 克隆项目到本地用来开发 git clone https://github.com/***/vue-prevent-brow ...

  4. vue-cli3+typescript+router

    vue基于类的写法,和基于对象的写法并不一致.使用vue-cli3创建的项目,src目录下的文件结构并没有多大区别,store.router.app.view.components.aeests该有的 ...

  5. JavaScript的switch循环

    <html> <head> <meta charset="utf-8"> <title>无标题文档</title> &l ...

  6. JavaScript与jquery的对比

      javascript jQuery 入口函数 只能有一个,如果有多个,后面的会覆盖前面 可以有多个,并且不会发生覆盖的情况 代码容错性 代码容错性差,代码出现错误,会影响到后面代码的运行. 代码容 ...

  7. 在AndroidManifest(清单文件)中注册activity(活动)及配置主活动、更改App图标、App名称、修改隐藏标题栏

    打开app/src/main/AndroidManifest. <?xml version="1.0" encoding="utf-8"?> < ...

  8. Spark Streaming 整合 Kafka

    一:通过设置检查点,实现单词计数的累加功能 object StatefulKafkaWCnt { /** * 第一个参数:聚合的key,就是单词 * 第二个参数:当前批次产生批次该单词在每一个分区出现 ...

  9. 关于Eclipse安装Scala插件不显示

    关于Eclipse安装Scala插件不显示, 改变java版本仍然不能使用, 办法还是有的:下载Eclipse Scala版本 解压使用 下载在这里:http://scala-ide.org/down ...

  10. PHP Base64 加密 & 解密

    <?php 加密: $cany = 'getshell.top'; #定义要加密的字符串 echo base64_encode($cany); #输出加密后的字符串 解密: $cany = 'Z ...