数据结构与算法之美笔记01----复杂度分析上

1.概念

数据结构:就是指一组数据的存储结构
算法:就是指操作数据的一种方法
要学习的常见的10种数据结构:数组、链表、栈、队列、散列表、二叉树、堆
跳表、图、trie树
要学习的常见的10种算法:递归、排序、二分查找、搜索、哈希算法、贪心算法、分治算法、回溯算法、动态规划、字符串匹配算法等

2.复杂度的分析

复杂度也叫渐进复杂度,包括时间复杂度和空间复杂度,用来分析算法执行效率和数据规模之间的增长关系,可以粗略地表示,越高阶复杂度的算法,执行效率越低

(1)大O复杂度表示法
T(n) = O(f(n))
T(n):代表代码的执行时间
n:表示数据规模的大小
f(n):代表没行会代码执行的次数总和
O:表示代码的执行时间T(n)与f(n)表达式成正比

(2)时间复杂度分析
1. 只关注循环执行次数最多的一段代码
我们在分析一个算法、一段代码的时间复杂度的时候,只关注循环执行次数最多的那一段代码就可以了。

  1. 加法法则:总复杂度等于量级最大的那段代码的复杂度
    平行用加法法则
    注意:只要是一个常量的执行时间,与n的规模无关,无论它多大,我们都当做.

  2. 乘法法则:嵌套代码的复杂度等于嵌套内外代码复杂度的乘积
    嵌套用乘法法则
    (3)几种常见时间复杂度实例分析
    数据结构与算法之美笔记01----复杂度分析上_第1张图片对于刚罗列的复杂度量级,我们可以粗略地分为两类,多项式量级和非多项式量级。其中,非多项式量级只有两个:O(2^n)和O(n!)。
    <1> O(1)
    只要代码的执行时间不随n的增大而增长,这样时间代码的复杂度我们都记作O(1)。或者说,一般情况下,只要算法中不存在循环语句、递归语句,即使有成千上万行代码,其时间复杂度也是O(1)。比如这段代码,即便有3行,它的时间复杂度也是O(1),而不是O(3)。

int i=6;
int j =8;
int sum =i+j;

<2> O(logn)、O(nlogn)
对数阶时间复杂度非常常见,同时也是最难分析的一种时间复杂度。举例说明:

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

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

2^0  2^1  2^2  2^3  2^4  ...  2^k ...  2^x =n

所以,我们只要知道x值是多少,就知道这行代码执行的次数了。通过2x=n求解x这个问题。x=log2^n,所以,这段代码的时间复杂度就是O(log2 ^n)。
现在,我把代码稍微改下,你再看看,这段代码的时间复杂度是多少?

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

很简单就能看出来,这段代码的时间复杂度为O(log3n)。实际上,不管是以2为底、以3为底,还是以10为底,我们可以把所有对数阶的时间复杂度都记为O(logn)。为什么呢?对数之间是可以互相转换的,log3^n就等于log3 ^2log2 ^ n,所以O(log3 ^n)=O(Clog2 ^n),其中C=log3 ^ 2是一个常量。基于我们前面的一个理论:在采用大O标记复杂度的时候,可以忽略系数,即O(Cf(n))=O(f(n))。所以,O(log2 ^ n)就等于O(log3 ^ n)。因此,在对数阶时间复杂度的表示方法里,我们忽略对数的“底”,统一表示为O(logn)。

O(nlogn)就很容易理解了。如果一段代码的时间复杂度是O(logn),我们循环执行n遍,时间复杂度就是O(nlogn)了。而且,O(nlogn)也是一种非常常见的算法时间复杂度。比如,归并排序、快速排序的时间复杂度都是O(nlogn)。

<3>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))。

空间复杂度

空间复杂度的全称是渐进空间复杂度(asymptotic space complexity),表示算法的存储空间与数据规模之间的增长关系。
常见的空间复杂度就是O(1)、O(n)、O(n2 ),像 O(logn)、O(nlogn) 这样的对数阶复杂度平时都用不到。
数据结构与算法之美笔记01----复杂度分析上_第2张图片

你可能感兴趣的:(数据结构与算法之美笔记01----复杂度分析上)