递归树:如何借助树来求解递归算法的时间复杂度?

递归树:如何借助树来求解递归算法的时间复杂度?

递归树与时间复杂度分析

递归就是将大问题分解成小问题来求解,将一层一层的分解过程画成图,其实就是一棵树,就是递归树

实战一:分析快排的时间复杂度

用递归树来分析快排的平均情况时间复杂度

每次分区之后,两个分区的大小比例是1:K,取k=9,即每次分区都很不平均,一个分区是另一个分区的9倍,快排过程中,每次分区都要遍历待分区区间的所有数据,所以,每一层分区操作所遍历的数据的个数之和就是n,递归树的高度是h,快排过程遍历的数据个数就是h * n,时间复杂度就是O(h*n)

快排结束的条件就是待排序的小区间大小为1,即叶子节点里的数据规模是1,从根节点n到叶子节点1,递归树中最短的一个路径每次都乘以 1 / 10 1/10 ,最长的一个路径每次都乘以 9 / 10 9/10 ,所以从根节点到叶子节点的最短路径是 l o g   2   n log~2~n ,最长的路径是 l o g   10 / 9   n log~10/9~n ,当分区大小比例是1:9,快排时间复杂度是 O ( n l o g n ) O(nlogn)

如果K = 99,分区及其不平均,两个分区大小是1:99,时间复杂度是多少呢?

K = 99 ,树的最短路径是log100n,时间复杂度仍然是 O ( n l o g n ) O(nlogn) ,不管底数多少,快排的时间复杂度就是 O ( n l o g n ) O(nlogn)

实战二:分析斐波那契数列的时间复杂度

int f (int n){
  if (n == 1) return 1;
  if(n == 2) return 2;
  return f(n-1) + f(n-2);
}

这棵递归树的高度是多少呢?f(n)分解成f(n-1)& f(n-2),每次数据规模都是 -1 -2,叶子规模是1 或者2,如果每次都是-1,最长路径是n,如果每次都是-2,最短路径是n/2

每次分解之后的合并操作只需要依次加法运算,从上往下,第一层总时间消耗是1,第二层总时间消耗是2,第三层总时间消耗是 2 2 2^2 ,……第k层的时间消耗是 2 ( k 1 ) 2^(k-1) ,整个算法的总时间消耗就是每一层时间消耗之和,整个算法的时间复杂度介于 O ( 2 n ) O(2^n) ,和 O ( 2 ( n / 2 ) ) O(2^(n/2)) 之间,时间复杂度是指数级的,非常高

实战三:分析全排列的时间复杂度

如何把n个数据的所有排列都找出来?

比如1,2,3三个数据,有6种不同的排列,那么如何通过编程打印一组数据的所有排列呢?可以用递归来实现

我们确定了最后一位数据,就变成了求解剩下n-1个数据的排列,而最后一位数据可以是n个数据中的任意一个,因此它的取值就有n种情况,所以“n个数据的排列”问题就分解成n个“n-1个数据的排列的子问题”

假设数组中存储的是1,2,3……n
f(1,2……n) = {最后一位是1,f(n-1)}  +  {最后一位是2,f(n-1)}   +  {最后一位是n,f(n-1)}
//调用方式:
//int[] a = {1,2,3,4} ;      printPermutations(a ,4,4);
//k表示要处理的子数组的数据个数

public void printPermutations(int[] data , int n , int k){
  if (k == 1){
    for (int i = 0 ;i < n ; ++ i){
      System.out.print(data[i] + " ");
    }
    System.out.println();
  }
  for(int i = 0;i < k ;++i){
    int tmp = data[i] ; 
    data[i] = data[k-1];
    data[k-1] = tmp;
    
    printPermutaations(data , n,k-1);
    
    tmp = data[i];
    data[i] = data[k-1];
    data[k-1] = tmp;
  }
}

每一层分解有n次交换操作,第二层有n个节点,每个节点分解需要n-1次交换,所以第二层总的交换次数是n*(n-1),第三层的交换次数是n*(n-1)(n-2),以此类推

一个细胞的生命周期是3个小时,一个小时分裂一次,求n个小时后,容器内有多少细胞?

以为递推公式是f(n) = f(n-1)*2 - f(n-3)

但是这是错的

因为第一个小时的2个细胞有一个已经在第三个小时死掉了,因此第四个小时只会死1个细胞,所以n=4的时候是13

1,2,4,7,13

死掉的细胞数并不是前3个小时新生的细胞和老细胞,因为老细胞在n时刻已经死掉了,此时死掉的细胞数应该是n-3时刻新生的细胞数,所以正确的递推公式是f(n) = 2f(n-1) - f(n-4)

if(n<0) return 0;
if(n == 0) return 1;
if(n ==1) return 2;
if(n ==2) return 4;
if(n == 3) return 7;

xiaozhuanlan.coom/topic/6091358742

发布了76 篇原创文章 · 获赞 9 · 访问量 9193

猜你喜欢

转载自blog.csdn.net/ywangjiyl/article/details/104382439