HEAP-DELETE(A,i)操作将节点i中的项从堆中删去

题目:HEAP-DELETE(A,i)操作将节点i中的项从堆中删去。对含n个元素的最大堆,请给出时间为O(lgn)的HEAP-DELETE的实现。

编程思路:

我们可以用堆中最后一个元素a[heapSize]放到节点i 位置,然后将heapSize减一。然后就涉及到堆调整以保持堆的性质。

调整的依据就是这最后一个元素a[heapSize]跟原来i节点的元素a[i]的相对大小,分三种情况:

(1)当a[heapSize]==a[i]时,最大堆不用调整。时间复杂度为O(1)

(2)当a[heapSize]<a[i]时,以i节点为根的子分支堆性质遭到破坏,其他地方不变,所以这里直接调用保持堆性质的函数MaxHeapIfy()进行堆调整即可。时间复杂度为O(lgn)

(3)当a[heapSize]>a[i]时,这种情况类似于“将优先队列的某个元素关键字值增大到k”的操作,所以直接调用HeapIncreaseKey()函数即可。时间复杂度为O(lgn)


实现代码如下:

  1. //堆调整,保持堆的性质    
  2. void MaxHeapIfy(int *a,int i,int heapSize)  
  3. {  
  4.     int largest=0;  
  5.     int left=0;  
  6.     int right=0;  
  7.     int tmp=0;  
  8.       
  9.     if(left<=heapSize&&a[i]<a[left])  
  10.     {  
  11.         largest=left;  
  12.     }  
  13.     else  
  14.     {  
  15.         largest=i;  
  16.     }  
  17.     if(right<=heapSize&&a[largest]<a[right])  
  18.     {  
  19.         largest=right;  
  20.     }  
  21.     if(i!=largest)  
  22.     {  
  23.         tmp=a[i];  
  24.         a[i]=a[largest];  
  25.         a[largest]=tmp;  
  26.         MaxHeapIfy(a,largest,heapSize);  
  27.     }  
  28. }  
  29.   
  30. //将堆中元素x的关键字值增大到k,k要大于x原关键字的值   
  31. void HeapIncreaseKey(int *a,int x,int k)  
  32. {  
  33.     int tmp=0;  
  34.     if(k<a[x])  
  35.     {  
  36.         return;  
  37.     }  
  38.     while(x>1&&a[x>>1]<a[x])  
  39.     {  
  40.         tmp=a[x];  
  41.         a[x]=a[x>>1];  
  42.         a[x>>1]=tmp;  
  43.           
  44.         x>>=1;  
  45.     }  
  46. }  
  47.   
  48. //删除堆中指定元素i   
  49. void HeapDelete(int *a,int i,int *heapSize)  
  50. {  
  51.     int tmp=a[*heapSize];  
  52.       
  53.     if(a[i]==tmp)  
  54.     {  
  55.         (*heapSize)--;  
  56.     }  
  57.     else if(a[i]>tmp)//i节点换成较小的tmp后,所在分支的最大堆性质可能遭到破坏,要进行调整   
  58.     {  
  59.         a[i]=tmp;  
  60.         (*heapSize)--;  
  61.         MaxHeapIfy(a,i,*heapSize);  
  62.     }  
  63.     else if(a[i]>tmp)//i节点的值增大到更大的tmp   
  64.     {  
  65.         (*heapSize)--;  
  66.         HeapIncreaseKey(a,i,tmp);  
  67.     }  
  68. }   
  69.   
  70. int main()  
  71. {  
  72.     return 0;  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值