优先级队列(Priority Queue)(二)

有些话、适合烂在心里 提交于 2020-02-12 12:19:33

在完全二叉树周插入元素的方法是插入到底层,上滤

在完全二叉树周删除元素的方法是将底层元素置于顶端,下滤

一.上滤

为插入词条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

 

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!