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

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

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

一.上滤

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

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值