A. 堆的简介
堆是一个很好用的数据结构,它既没有搜索二叉树那样严格(要求左子结点必须小于父结点,而右子结点必须不小于左子结点),同时也可以毫不费力气地维护平衡的高度(实现过平衡二叉树的就知道,挺麻烦的)。
堆可以按照它的性质分为最大堆(任意父结点不小于左右子结点)和最小堆(任意父结点不大于左右子结点),两种原理都是一样的,下面就最大堆来讨论。
首先是堆的底层数据的结构,只用到了一个普通的数组!!!没错,没有眼花,就是这样而已,不需要任何指针,简单直观的下标访问——假设父结点的下标为i,那么它的子结点下标分别是:2i(左),2i + 1(右);那么反过来,已知某节点的下标为x,那么它的父结点的下标就是x/2,不管它是左还是右。注意到这里的运算都是跟2的乘法或除法,所以可以用位移运算来加快速度(取下标的操作是很频繁的,积少成多),比如:
size_t Heap::Parent(size_t i) {
return i >> 1;
}
size_t Heap::Left(size_t i) {
return i << 1;
}
size_t Heap::Right(size_t i) {
return (i << 1) +