堆排序中--建堆的算法复杂度分析O(n)

代码:

  1. template<class T> inline void MaxHeap<T>::make_heap(vector<T> & v) {  
  2.     if (heap_.size() != 0)  
  3.         heap_.clear();  
  4.     heap_ = v;  
  5.   
  6.     // start with last parent, and reheapify_down back to root  
  7.     for (int i = parent(v.size() - 1); i >= 0; i--)  
  8.         reheapify_down(i);  
  9.   
  10.     v = heap_;  
  11. }  


  1. template<class T> inline void MaxHeap<T>::reheapify_down(int i) {  
  2.     if (heap_.empty())  
  3.         return;  
  4.   
  5.     int current = i, max = i;  
  6.     int left = 1, right = 2;  
  7.     int size = heap_.size();  
  8.   
  9.     do {  
  10.         current = max;  
  11.         left = left_child(current);  
  12.         right = right_child(current);  
  13.         if (left < size && heap_[left] > heap_[current])  
  14.             max = left;  
  15.         if (right < size && heap_[right] > heap_[max])  
  16.             max = right;  
  17.         if (max != current)  
  18.             swap(heap_[current], heap_[max]);  
  19.     } while (max != current);  
  20. }  

 

看似建堆(make_heap)的复杂度为O(nlogn),实则为O(n),reheapify_down不会touch到每个节点,所以不算简单的递归,只能算叠加。证明如下:


因为堆构建的是一颗平衡二叉树。于是有:

1. 一棵拥有n个节点的平衡二叉树,树高 h 约为 lg n 。

2. 树的第 i 层 最多有节点 2^i 个。注意,第 i 层的高度为 i + 1。如第0层的高度为1,拥有1个根节点。


那么做reheapify_down时,最底层(h-1)的节点不会动,倒数第二层(h-2)的节点最多往下移动一次,倒数第三层(h-3)的节点最多往下移动2次....第0层的节点往下最多移动(h-1)次。

所以,最坏情况下,每层所有节点都会往下移到最底层。

则,所有操作总和为     S = 2^(h-1)*0 + 2^(h-2)*1 + 2^(h-3) * 2 + ... + 2^1*(h-2) + 2^0*(h-1)        ----- (1)

把(1)式乘以2,再减去(1)式, 可得

S = 2^(h-1) + 2^(h-2) + ... + 2^1 - 2^0*(h-1)  = 2(1-2^(h-1))/(1-2) - (h-1) = 2^h - h- 1      ---- (2)

把h = lg n 代入 (2)式, 得 S = n - lgn - 1 <= n   (n >=1)


故而, 建堆复杂度为O(n) 。



水平有限,欢迎指正不对之处。

转自http://blog.csdn.net/mitkook/article/details/8058682

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值