###堆排序
- 堆排序的执行流程
- 对序列原地建堆
- 交换堆顶元素和尾元素
- 堆元素数量 -1
- 把交换到堆顶的元素进行下滤操作
- 循环执行 2-4,直至堆中元素只剩一个
原地建堆:
private func heapfiy(){
var i = (size >> 1) - 1
while i >= 0 {
siftDown(indexShape: i)
i -= 1
}
}
元素下滤:
/// 让index位置的元素下滤
/// - Parameter index: <#index description#>
private func siftDown(indexShape:Int){
var index = indexShape
let element = elements[index]
let half = size >> 1
// 第一个叶子节点的索引 == 非叶子节点的数量
// index < 第一个叶子节点的索引
// 必须保证index位置是非叶子节点
while index < half {
// index的节点有2种情况
// 1.只有左子节点
// 2.同时有左右子节点
// 左子节点
var leftChildIndex = (index << 1) + 1
var leftChild = elements[leftChildIndex]
// 右子节点
let rightChildIndex = (index << 1) + 2
// 默认左子节点与父节点进行比较
if rightChildIndex < size && elements[rightChildIndex] > elements[leftChildIndex] {
leftChild = elements[rightChildIndex]
leftChildIndex = rightChildIndex
}
if element > leftChild {
break
}
// 将子节点存放到index位置
elements[index] = leftChild
// 重新设置index
index = leftChildIndex
}
elements[index] = element
}
交换第0元素位置和末尾值:
private func sort(){
while size > 1 {
// 第0个最大值交换到数组最后
let temp = elements[0]
elements[0] = elements[size - 1]
elements[size - 1] = temp
size -= 1
// 下滤恢复最大堆性质
siftDown(indexShape: 0)
}
}
-
选择排序的稳定性
- 选择排序属于不稳定的排序
-
选择排序的时间复杂度和空间复杂度
- 时间复杂度 时间复杂度为O(nlogn)
- 空间复杂度
- O(1)
- 属于原地算法
###堆的概念 TODO:待补充
源码及单元测试:github.com/yukifeng/su…