Heap Sort
普通队列:先进先出;后进后出
优先队列:出队顺序和入队顺序无关;和优先级有关
如操作系统每次动态选择优先级最高的任务执行
人工智能中选择当前要攻击的对象
在1,000,000个元素中选出前100名(在N个元素中选出个元素)
1) 先排序(NlogN)
2) 使用优先队列(NlogM)
优先队列主要操作
1)入队
2)出队(取出优先级最高的元素)
堆的实现

不意味着层数越高
,数值越大
用数组存储二叉堆
父节点下标i
(从1开始)
左子结点下标2i
,右子结点下标2i+1
parent(i)
= i / 2left child(i)
= 2iright child(i)
= 2i+1
Shift Up
新添加一个元素到最后
count++
将最后一个元素一步一步向上挪
|
|
Shift Down
拿出根元素
把最后一个元素拿到根结点
将根结点一步一步向下挪
|
|
堆排序版本1
|
|

堆排序版本2(Heapify)
给定一个数组,让这个数组组成堆的形状(heapify,快速建堆)
快速建堆
对于一个完全二叉树,第一个非叶子结点的索引下标(元素个数/2)
从后向前考察每一个非叶子结点
|
|

系统级别数据很少用堆排序
堆排序主要用于动态数据的维护
为什么建堆快?
因为:
将n各元素逐个插入到一个空堆中O(nlogn)
heapify的过程,复杂度O(n)
原地堆排序(空间O(1)复杂度)
先heapify建堆,取出首元素(最大),与最后元素交换
元素个数减一,将首元素调整,重新调整堆,将首元素与最后元素交换
……
此过程依次类推
排序算法总结
插入排序,当数组几乎有序的情况,插入排序会变成O(N)
快速排序,当在极特殊的情况下,快速排序会退化到O(N^2) (用随机化,使得退化的可能变得极地)
快速排序在O(nlogn)排序中常数占优
在右大量重复元素的情况下用三路归并排序
(原地排序:是否可以直接在原数组中排序)
快排空间(nlogn):因为采用递归的方法 ,递归过程有logn层,需要logn层的栈空间

比如先按字典序排序,稳定排序可以保证:按成绩排序之后,相同成绩的学生仍然按名字的字典序来排序
排序的稳定性和实现方法有关,如果实现不好的话,会将插入排序和归并排序实现为不稳定的排序