定义
删除最大元素和插入元素的数据结构称为:优先队列
通过优先队列我们依次删除记录最大元素便实现了一种排序方法称之为:堆排序
可以用堆排序进行排序的完全二叉树,并且用数组表示称为二叉堆
若定义二叉堆中每个父节点都大于等于子节点为:堆有序
二叉堆
数据结构
数组结构:数组0为空,1为根节点,下标为k的的子节点2k,2k+1。
下方元素上浮:swim
通过每次和父节点(k节点的父节点为k/2)进行比较,若大于父节点则交换,然后继续往上比较(可以看到只和父节点进行了比较)(比较一次,交换一次)
上方元素下沉:sink
每次和左右子节点进行比较,左子节点为2k,右子节点为2k+1,选出其中较大的,若改子节点大于自身,则进行交换,继续往下比较(比较两次,交换一次)
插入元素
插入数据末尾后,执行swim操作,可以保证该元素到一个合适的位置
删除元素
删除最大元素后,需要把末尾元素放入顶部,执行sink操作,这样保证每个节点都能被比较到,确保顶部一定是最大元素。
排序方法
实现堆排序分两个阶段:第一个是构建堆,第二个阶段是依次进行交换最大元素。
构建堆有两种方式
- 从左到右依次插入执行swim方法
- 从倒数第二层开始,也就是末尾元素的父节点开始,若有k个元素,则从k/2节点开始,从右往左进行sink操作。假设有7个元素一个数组,我们依次在3,2,1位置执行sink操作
该方法相比于swim构建堆方法,减少了接近一半的交换次数
依次进行删除最大元素
循环执行两步骤,第一步交换末尾和首位元素,长度-1,第二步执行对首位执行sink方法。
总结
目前常有的几种排序:选择排序,插入排序,归并排序,快速排序,堆排序
| 稳定性 | 原地排序 | 时间复杂度 | 空间复杂度 | 备注 | |
|---|---|---|---|---|---|
| 选择 | 否 | 是 | N^2 | 1 | |
| 插入 | 是 | 是 | N~N^2 | 1 | 取决输入的顺序排列情况 |
| 归并 | 否 | 否 | N*logN | N | |
| 快速 | 否 | 是 | N*logN | logN | 由概率保证 |
| 堆排 | 否 | 是 | N*logN | 1 |