码迷,mamicode.com
首页 > 其他好文 > 详细

建堆复杂度O(n)证明

时间:2018-02-01 14:56:19      阅读:164      评论:0      收藏:0      [点我收藏+]

标签:循环   heap   blog   递归   log   vector   一个   需要   上界   

堆排序中首先需要做的就是建堆,广为人知的是建堆复杂度才O(n),不过很少有人去了解过这个复杂度的证明过程,因为不是那么直观地可以一眼就看出来。本文不讲堆排序,只单纯讲建堆过程

建堆代码

欲了解复杂度的计算过程,必先看懂建堆代码。先看这个建堆过程

// 将arr[n]向上调整至合适位置
void AdjustHeap(vector<int> &arr, int n)
{
    if(n<=0) return ;
    if(arr[(n-1)/2] > arr[n]) {  //与父结点比较
        swap(arr[(n-1)/2], arr[n]);
        AdjustHeap(arr, (n-1)/2);   //递归调整
    }
}
// 小根堆
void BuildHeap(vector<int> &arr)
{
    for(int i=1; i<arr.size(); i++) {
        AdjustHeap(arr, i);
    }
}

因为不讲堆排序,所以这里用的是向上调整即可,更加直观易懂。相信这么简单的代码你应该能看懂它的原理。

复杂度计算

从直观上看,AdjustHeap()的调用深度最多为logn层,故复杂度上限为O(logn)。而BuildHead()中的循环为n-1次,故它的复杂度为O(nlogn),但这不是它的实际平均复杂度,而是一个估算的上界,它很可能永远达不到这个上界。下面来分析一下。

AdjustHeap(arr, 1) 比较次数最多为1次,最少为1次。
AdjustHeap(arr, 2) 比较次数最多为1次,最少为1次。
AdjustHeap(arr, 3) 比较次数最多为2次,最少为1次。
AdjustHeap(arr, 4) 比较次数最多为2次,最少为1次。
AdjustHeap(arr, 5) 比较次数最多为2次,最少为1次。
AdjustHeap(arr, 6) 比较次数最多为2次,最少为1次。
AdjustHeap(arr, 7) 比较次数最多为3次,最少为1次。
...
AdjustHeap(arr, n-1) 比较次数最多为logn次,最少为1次。

按最坏情况来算,将这些比较次数累加起来就是建堆的时间复杂度,显然最佳情况是O(n)。而最坏情况的比较次数复杂一些,为了方便计算,假设n是2的k次幂,则k = logn
\({1 + 1 + 2 + 2 + 2 + 2 + 3 + 3 + ... + k}\)
= \({1*2^1+2*2^2+3*2^3}+\cdots + {k*2^k}\)
=

建堆复杂度O(n)证明

标签:循环   heap   blog   递归   log   vector   一个   需要   上界   

原文地址:https://www.cnblogs.com/xcw0754/p/8398535.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!