引入
随着科技的发展,日益趋显的是我们对效率的要求越来越高了。当然,说到我们的算法也不例外。
算法效率分析分为两种:第一种是时间效率,第二种是空间效率。时间效率被称为时间复杂度。而空间效率被称作空间复杂度。时间复杂度主要街量的是一个算法的运行速度,而空间复杂度主要衡量一个算法所需要的额外空间,在计算机发展的早期,计算机的存储容量很小。所以对空间复杂度很是在子。但是经过计算机行业的迅速发展,计算机的存储容量已经达到了很高的程度。所以我们如今已经不需要再特别关注一个算法的空间复杂度。那我们先来看一下时间效率,也就是时间复杂度。
一、时间复杂度的详解及例题
1、时间复杂度的概念
时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。通俗来讲,我们只需要计算出大概的次数,时间复杂度就是在一个算法中执行次数最多的一个循环。
我们来结合着例题一起看一下,这样更加容易理解。
2、时间复杂度的例题训练
2.1 实题训练1
我们看下面的一段代码的时间复杂度为多少呢?
我们先来看一下上面的代码总执行的次数吧。
我们不难看出,第一个for循环执行的次数为N*N次,第二个for循环执行的次数为2*N次,while循环执行了10次。那么总次数即为F(N)=N*N+2*N+10。我们再看下面的表格:
F(N)与N和N*N的变化对比
N |
N*N | F(N) |
10 | 100 | 130 |
100 | 10000 | 10210 |
1000 | 1000000 | 1002010 |
从上面的表格我们不难看出,当N越大时,N*N对F(N)的影响最大,其他项的影响极小,甚至可以忽略不计。于是我们实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数,那么这里我们使用大O的渐进表示法。大O符号(Big O notation):是用于描述西数渐进行为的数学符号。我们来看一下推导大O阶方法:
用常数1取代运行时间中的所有加法常数。
在修改后的运行次数函数中,只保留最高阶项。
如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。
使用大O的渐进表示法以后,我们可以计算出Func1的时间复杂度为:
O(N*N)
2.2 实题训练2
我们再来看一个例题:
这里我们使用大O的渐进表示法,很容易可以看出来时间复杂度。当M远大于N时,时间复杂度为O(M),当M和N差不多大时,时间复杂度为O(M)或者O(N)。
2.3 实题训练3
我们再来看一个简单的为常数的:
同样, 这里我们使用大O的渐进表示法,我们可以看出上面的代码执行了100次,我们通过大O阶方法的第一条规则可以看出,时间复杂度为O(1)。
2.4 实题训练4
通过上面我们会发现大0的渐进表示法去掉了那些对结果影响不大的项,简洁明了的表示出了执行次数。
另外有些算法的时间复杂度存在最好、平均和最坏情况:
最坏情况:任意输入规模的最大运行次数(上界)。
平均情况:任意输入规模的期望运行次数。
最好情况:任意输入规模的最小运行次数(下界)。
例如:在一个长度为N数组中搜索一个数据x
最好情况:1次找到。
最坏情况:N次找到。
平均情况:N/2次找到。
在实际中一般情况关注的是算法的最坏运行情况,所以数组中搜索数据时间复杂度为O(N) .
实际的例子有我们常见的:冒泡排序,二分查找等等。这些的时间复杂读我们都要看最坏的情况。
2.5 大O符号(Big O notation)的函数绘图
需要注意的是,在这里的logN,N为元素的个数。这个在二分查找中很容易解释。假设我们查找了X次,因为每次查找去掉了一般元素,那么实际的元素个数N=2^X,那么X=logN(以2为底)。
通过上图来看,时间效率从上往下,依次降低。
二、空间复杂度的详解及例题
1、空间复杂的的概念
空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度。空间复杂度不是程序占用了多少bytes的空间,因为这个也没大大意义,所以空间复杂度算的是变量的个数。空间复杂度计算规则基本跟实践复杂度类似,也使用大O渐进表示法。
2、空间复杂度的例题
2.1 实题训练1
我们先来看一个相对较为简单的例题:
我们先来看一下总共变量的个数。这里要注意的是malloc动态开辟了一块空间,这里相当于就是开辟了一个动态数组。其中变量的个数为n+1,还有一个n变量,则总共有n+2个变量。使用大O渐进表示法,常数直接去掉。则空间复杂度为O(N)。
2.2 实题训练2
我们再来看一个相对较难理解的一个例题:
其实这里应用了函数的递归。很容易看出调用了N-1次函数,每次调用时都会为函数创建栈帧,每个函数的栈帧中都会有常数个变量(时间复杂度为O(1))。调用了N-1次,那么运用大O渐进法很容易得出该函数的空间复杂度为O(N).
好了,我们今天就学到这里,希望以上的内容对你的理解有一个很好的帮助。
感谢您的观看,后续还会一直更新哦ovo!