《数据结构与算法之美》读后感——04(上)

一、为什么要做复杂度分析

精确的计算算法的效率的方法——事后统计法。通过监控程序执行的时间和使用的内存,来评价程序的执行效率。

事后统计法的不足:

1.不同的机器的运行的结果可能不同,例如机器的cpu越快,代码的执行效率越高。

2.数据对算法的执行效率有很大的影响。以排序算法为例,如果数据已经是有序了的,执行的时间很短,如果数据是逆序的,执行的时间是最长的。

二、什么是复杂度分析

复杂度分析是通过一定的方法总结出一种算法的执行效率随着数据规模的变化而变化的规律的过程。

三、复杂度有哪些

时间复杂度和空间复杂度

四、时间复杂度是什么,怎么算

时间复杂度:算法的执行时间随着数据规模的变化而变化的规律。

计算方法:

1.计算执行次数最多的代码段

观察代码被执行次数与数据规模有关的部分,其他部分就算时执行了十万次,可以当作常量,重点关注的地方有:循环、递归、函数调用(被调用的函数里面的重点关注的地方)

2.加法法则

代码中有两个部分和数据规模有关的部分,则时间复杂度可以是两部分相加,然后去量级最大的。

3.乘法法则

代码中嵌套的两个和数据规模有关的部分,总的时间复杂度为两者的时间复杂度的乘积

五、常见的时间复杂度分析

O(logn)、O(nlogn)

i=1;
 while (i <= n)  {
   i = i * 2;
 }

从代码中可以看出,变量i的值从1开始取,每循环一次就乘以2。当大于n时,循环结束。还记得我们高中学过的等比数列吗?实际上,变量i的取值就是一个等比数列。如果我把它一个一个列出来,就应该是这个样子的:

所以,我们只要知道x值是多少,就知道这行代码执行的次数了。通过2x=n求解x这个问题我们想高中应该就学过了,我就不多说了。x=log2n,所以,这段代码的时间复杂度就是O(log2n)。

O(m+n)、O(m*n)

代码的复杂度由两个数据的规模来决定

int cal(int m, int n) {
  int sum_1 = 0;
  int i = 1;
  for (; i < m; ++i) {
    sum_1 = sum_1 + i;
  }

  int sum_2 = 0;
  int j = 1;
  for (; j < n; ++j) {
    sum_2 = sum_2 + j;
  }

  return sum_1 + sum_2;
}

从代码中可以看出,m和n是表示两个数据规模。我们无法事先评估m和n谁的量级大,所以我们在表示复杂度的时候,就不能简单地利用加法法则,省略掉其中一个。所以,上面代码的时间复杂度就是O(m+n)。

针对这种情况,原来的加法法则就不正确了,我们需要将加法规则改为:T1(m) + T2(n) = O(f(m) + g(n))。但是乘法法则继续有效:T1(m)*T2(n) = O(f(m) * f(n))。

六、时间复杂度可能的取值

O(1) 、O(logn)、O(n)、O(nlogn)、O(n^2)

七、空间复杂度是什么,怎么算

空间复杂度:算法执行时需要用到的内存空间

计算方法:

只看内存占用和数据规模相关的变量,其他的变量可以看作常量忽略。

常见的空间复杂度就是O(1)、O(n)、O(n2 )

你可能感兴趣的:(数据结构和算法)