堆排序(HeapSort)
2015-09-25 15:52
363 查看
一、相关介绍
堆排序(HeapSort),与归并排序一样,但不同于插入排序的是,堆排序的时间复杂度是O(nlgn),空间复杂度是O(n)。而与插入排序相同,但不同于归并排序的是,堆排序同样具有空间原址性:任何时候都只需要常熟个额外的元素空间存储临时数据。堆排序引入的算法设计技巧:使用一种我们称为“堆”的数据结构来进行信息管理。堆不仅用于堆排序中,而且它也可以构造一种有效的优先队列。
虽然“堆”这一词源自堆排序,但是目前它已经被引申为“垃圾收集存储机制”,例如在Java和Lisp语言中所定义的。强调一下,这里使用的堆不是垃圾收集存储,而是堆数据结构。
二、定义
堆排序(HeapSort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。(二叉)堆是一个数组,它可以被看成一个近似的完成二叉树。树上的每一个结点队友数组的一个元素。除了最底层外,该树是完全充满的,而且是从左向右填充。表示堆的数组A包含属性:heapSize表示有多少个堆元素存储在该数组中。也就是说,虽然A[1..A.length]可能存有数据,但只有A[1..A.heapSize]中存放的是堆的有效元素,这里,
0 <= A.heapSize <= A.length
树的根节点是A[0]
三、最大堆和最小堆
二叉堆可以分为两种形式:最大堆和最小堆。在这两种堆中,节点的值都是满足堆的性质,但一些细节定义则有所差异。在最大堆中,最大堆性质是指除了根以外的所有节点i都要满足:
A[parent(i)] >= A[i]
也就是说,某个节点的值至多与其父结点一样大。因此,堆的最大元素存放在根节点中;并且,在任一子树中,该子树所包含的所有节点的值都不大于该子树根节点的值。
最小堆的组织方式正好相反:最小堆性质是指除了根以外的所有节点i都有
A[parent(i)] <= A[i]
最小堆中的最小元素存放根节点中。
四、源代码
// // Heap.swift // 堆排序 // // Created by 阳君 on 14/12/12. // Copyright (c) 2014年 六月. All rights reserved. // import Foundation /// 堆排序 class Heap { /// 数组 private var list:[Int] = [] /// 堆长度 private var heapSize = 0 //MARK: 初始化 init(list:[Int]) { self.list = list } //MARK: 最大堆排序 func maxSort() -> [Int]{ self.buildMaxHeap() for(var i = self.heapSize - 1; i > 0; i--) { self.exchange(i, change: 0) self.heapSize-- self.maxBase(0) } return self.list } //MARK: 最小堆排序 func miniSort() -> [Int]{ self.buildMiniHeap() for(var i = self.heapSize - 1; i > 0; i--) { self.exchange(i, change: 0) self.heapSize-- self.miniBase(0) } return self.list } // MARK: - 父节点 private func parent(i:Int) -> Int { return (i + 1) / 2 - 1 } // MARK: 左节点 private func left(i:Int) -> Int { return 2 * i + 1 } // MARK: 右边节点 private func right(i:Int) -> Int { return 2 * i + 2 } // MARK: 交换节点 private func exchange(i:Int, change:Int) { let tempI:Int = self.list[i] self.list[i] = self.list[change] self.list[change] = tempI } // MARK: - 建立最大堆 private func buildMaxHeap() { self.heapSize = self.list.count for(var i = self.list.count / 2; i >= 0; i--) { self.maxBase(i) } } // MARK: 最大堆的基础算法 private func maxBase(i:Int) { let l = self.left(i) let r = self.right(i) var largest = i // 找出最大的那个数 if l < heapSize && self.list[l] > self.list[largest] { largest = l } if r < heapSize && self.list[r] > self.list[largest] { largest = r } // 是非需要改变 if largest != i { self.exchange(i, change: largest) self.maxBase(largest) } } // MARK: - 建立最小堆 private func buildMiniHeap() { self.heapSize = self.list.count for(var i = self.list.count / 2; i >= 0; i--) { self.miniBase(i) } } // MARK: 最小堆的基础算法 private func miniBase(i:Int) { let l = self.left(i) let r = self.right(i) var largest = i // 找出最小的那个数 if l < self.heapSize && self.list[l] < self.list[largest] { largest = l } if r < self.heapSize && self.list[r] < self.list[largest] { largest = r } // 是非需要改变 if largest != i { self.exchange(i, change: largest) self.miniBase(largest) } } }
五、测试
1. 测试代码
var list:[Int] = [] for(var i = 0; i < 5; i++) { list.append(i) } for(var i = -2; i < 6; i++) { list.append(i) } let heap = Heap(list: list) println("最大堆排序:\(heap.maxSort())") println("最小堆排序:\(heap.miniSort())")
2. 结果
最大堆排序:[-2, -1, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5]最小堆排序:[5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 0, -1, -2]
相关文章推荐
- 详解Java GC的工作原理+Minor GC、FullGC
- Android 简介json解析的使用
- Makefile中常用的函数
- 第三方库写能看的文档有多重要?
- swift开发笔记8 - sqlite3数据的使用(xcode 7,ios9)
- USB驱动——USB配置
- java获取相对时间 1小时前 1天前
- 函数指针数组
- win7下sqlite3cmd下中文乱码
- 【Android】 从头搭建视频播放器(2)——SystemMediaPlayerImpl
- iOS项目开发实战——UIView的层级关系
- 关与RVDS2.2仿真时AXD的configure target 里面是空的问题解决
- 解决后台传到前台的值是中文乱码的问题
- WPF解析TTF 字体
- MyEclipse导入的项目js文件乱码
- 内部接口
- java日期时间操作
- Sip响应状态码功能对照详解
- Porting openwrt on MT7688 Log
- JQuery DataTable 1.10服务端分页实现