在完全二叉树周插入元素的方法是插入到底层,上滤
在完全二叉树周删除元素的方法是将底层元素置于顶端,下滤
一.上滤
为插入词条e,只需要将e作为末尾元素接入向量
否则,e与其父节点换位
否则,e再与父节点换位
不断重复,直到e与其父亲满足堆序性,或者e达到堆顶(没有父亲)
二.代码实现
template <typename T> void PQ_ComplHeap<T>::insert ( T e ) { //将词条插入完全二叉堆中
Vector<T>::insert ( e ); //首先将新词条接至向量末尾
percolateUp ( _size - 1 ); //再对该词条实施上滤调整
}
//对向量中的第i个词条实施上滤操作,i < _size
template <typename T> Rank PQ_ComplHeap<T>::percolateUp ( Rank i ) {
while ( ParentValid ( i ) ) { //只要i有父亲(尚未抵达堆顶),则
Rank j = Parent ( i ); //将i之父记作j
if ( lt ( _elem[i], _elem[j] ) ) break; //一旦当前父子不再逆序,上滤旋即完成
swap ( _elem[i], _elem[j] ); i = j; //否则,父子交换位置,并继续考查上一层
} //while
return i; //返回上滤最终抵达的位置
}
时间复杂度:O(log(n))
改进:常系数意义上的改进,原来的swap操作的时间复杂度是O(3log(n)),现在可以先将要插入的值e保存,然后依次上滤,最后再将该值赋给最终的位置,这样改进之后的时间复杂度是O(log(n))+2
三.下滤
摘除向量的首元素,代之以末元素e,//结构性保持;若堆序性依然保持则完成,
否则,//即e与孩子们违背堆序性
e与孩子们中的大者换位
//若堆序性因此恢复,则完成,
否则,
e再次与孩子们中的最大者换位
四.代码实现
template <typename T> T PQ_ComplHeap<T>::delMax() { //删除非空完全二叉堆中优先级最高的词条
T maxElem = _elem[0]; _elem[0] = _elem[ --_size ]; //摘除堆顶(首词条),代之以末词条
percolateDown ( _size, 0 ); //对新堆顶实施下滤
return maxElem; //返回此前备份的最大词条
}
//对向量前n个词条中的第i个实施下滤,i < n
template <typename T> Rank PQ_ComplHeap<T>::percolateDown ( Rank n, Rank i ) {
Rank j; //i及其(至多两个)孩子中,堪为父者
while ( i != ( j = ProperParent ( _elem, n, i ) ) ) //只要i非j,则
{ swap ( _elem[i], _elem[j] ); i = j; } //二者换位,并继续考查下降后的i
return i; //返回下滤抵达的位置(亦i亦j)
}
时间复杂度:O(log(n))
改进:与上滤类似,改进swap
来源:CSDN
作者:bestrivern
链接:https://blog.csdn.net/bestrivern/article/details/104221681