建立最大堆
- 用数组按层次遍历的顺序表示二叉树,array[0]表示根节点。
- 该二叉树显然是个完全二叉树,因此满足:对于节点array[index],其左节点为array[index2+1],右节点为array[index2+2]。换句话说,对于节点array[index],其父节点为[(index-1)/2]
- 建立最大/小堆:最后一个具有子树的节点的index=array.Length-1,即array[(array.Length-1)/2],从该节点开始(因为对于叶节点单个来说,本身就是有序的),从后往前迭代。
- 对于迭代的每一个节点,进行堆调整操作:找出自身与左右子节点(如果存在)中的最大者,将其与自身交换。如果发生了交换,需要对被交换的子节点继续进行堆调整(递归调用),如果自身就是最大者则无需交换(同时也是递归结束条件,涵盖了叶节点的情况,因为叶节点没有子节点,找出的最大者就是自身)
插入
- *不需要index参数,而是直接将元素插入到array.Length位置(因为不论从哪里插入,最终仍会调整为最大堆)
- 对该节点进行堆调整操作
- (关于超出数组容量的问题,可以抛出异常也可以再进行扩容)
删除index节点
- 将待删除节点index与最后一个节点交换(或直接将最后一个节点赋值给被删除的节点也行)
- 对节点array[index]进行堆调整操作
堆排序
不断删除最后一个元素并输出,即可得到排序后的序列
补充
堆调整操作中的交换操作是造成堆排序是不稳定的原因