数据结构之时间复杂度

大O表示法:算法的时间复杂度通常用大O符号表述,定义为T[n] = O(f(n))。称函数T(n)以f(n)为界或者称T(n)受限于f(n)。 如果一个问题的规模是n,解这一问题的某一算法所需要的时间为T(n)。T(n)称为这一算法的“时间复杂度”。当输入量n逐渐加大时,时间复杂度的极限情形称为算法的“渐近时间复杂度”。

迭代程序

  • 题目:
int i=1;
while(i<=n) {
    i=i*2;
}
  • 思路:
    假设循环执行了k次,那么\(2^k\)≤n,则k≤logn,所以时间复杂度为T(n)=O(logn)

递归程序

主方法

  • 分治法主定理:T[n] = aT[n/b] + f(n),其中n为问题规模a≥1 and b>1 是常量,并且f(n)是一个渐进正函数,也就是递归以外的计算时间,为了使用这个主定理,需要考虑下列三种情况:
    • 如果f(n)=O(\(n^{log_ba-ε}\))(即 f(n)的指数小于\({log_ba}\)),对于某个常量ε>0成立(即 f(n)为\(n^{log_ba}\)的低阶无穷大),那么T(n)=O(\(n^{log_ba}\))(即 时间复杂度取决于高阶无穷大
    • 如果f(n)=O(\(n^{log_ba}\))(即 f(n)的指数等于\({log_ba}\))(即 f(n)为\(n^{log_ba}\)的同阶无穷大),那么T(n)=O(\(n^{log_ba}logn\))

    • 如果f(n)=O(\(n^{log_ba+ε}\))(即 f(n)的指数大于\({log_ba}\)),对于某个常量ε>0成立,并且af(n/b)≤cf(n),对于某个常量c<1(n足够大)成立(即 f(n)为\(n^{log_ba}\)的高阶无穷大),那么T(n)=O(f(n))

  • 题目:
    T(n)=3T(n/2)+n^2
  • 思路:
    1. 试试能不能使用主方法,a=3,b=2,f(n)=n^2满足条件
    2. 看看满足哪一种情况,由于\(log_23\)<2,且\(3n^2/4 < cn^2\)(c<1),满足第三种情况,所以T(n)=O(n^2)

迭代法

  • 题目:
//汉诺塔问题,假定move()的时间复杂度为O(1)
void hanoi(int n, char x, char y, char z) {
    if(n == 1) {
        move(x, 1, z);
    }else {
        hanoi(n-1, x, z, y);
        move(x, n, z);
        hanoi(n-1, y, x, z);
    }
}
  • 思路:
    1. 首先写出表达式:T(n) = 2T(n-1)+O(1) (即 你的问题规模分解成了2个n-1的问题规模加上执行了一次基本操作move()
    2. 试试能不能使用主方法,发现a=2,b=1,f(n)=O(1),不满足b>1的条件,不能使用
    3. 采用迭代法,因为每次迭代n的数据规模减少1,到最后必然会有终点,即n==1。


      T(n)=2T(n-1)+1
      T(n-1)=2T(n-2)+1
      联立,得
      T(n)=4T(n-2)+1+2
      由数学归纳法,得
      T(n)=2^(n-1)T(1)+1+2+4+8+...+2^(n-2)
      又∵终止条件T(1)=1
      ∴时间复杂度为O(2^n)

猜你喜欢

转载自www.cnblogs.com/blknemo/p/11365724.html