前言
通过前面的学习了解到数据结构一般可以分为逻辑结构和物理结构。
其中逻辑结构分为集合结构、线性结构、树形结构和图形结构。物理结构分为顺序存储结构和链式存储结构。
同时算法的5个基本特性,分别是输入、输出、有穷性、确定性和可行性。最后了解到一个好的算法需要遵守正确性、可读性、健壮性、时间效率高和存储量低。其实,实现效率和存储量就是时间复杂度和空间复杂度。本次学习笔记总结了两个"复杂度"的相关知识点。在真正的开发中,时间复杂度尤为重要,空间复杂度不做太多说明。
时间复杂度
时间复杂度的定义
定义:在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)的数量级。(基本操作的总次数)
算法的时间复杂度,也就是算法的时间量度,记作:
T(n)= O(f(n))。
它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐近时间复杂度,简称为时间复杂度。其中f(n)是问题规模n的某个函数。
时间复杂度的计算
1、求出函数f(n)之后,取出f(n)中随n增大而增长最快的的项,然后将其系数变为1。
2、将增长最快的项系数化为1后的结果,作为时间复杂度的度量,
3、函数中增长最快的项 / 此项的系数。
例如 f(n)=5n³ +5n² +220,则其时间复杂度计算为 T(n)=O(5n³/5)=O(n³)
PS:
有些算法中基本操作的执行次数不仅跟初始输入的数据规模有关,还和数据本身有关。例如一些排序算法,同样都是n个待处理数据,但是数据初始的有序性不同,则基本操作的执行次数也不同。所以依照使得基本操作执行次数最多的输入来计算时间复杂度,就是将最坏的情况作为算法时间复杂度的度量。
举例
例子1
c = b;//执行1次
b = a;//执行1次
a = c;//执行1次
所以T(n)= 3 = O(1)。
注意:如果算法的执行时间不随着问题规模n的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。此类算法的时间复杂度是O(1)。
例子2
for (int i = 1; i <= n; i ++) {//执行n次
for (int j = 1; j <= n; j ++) {//执行n^2次
sum+= 1;//执行n^2次
}
}
所以:T(n) = n + n^2 +n^2 = O(n^2)
PS:嵌套循环的时间复杂度等于行最内层语句执行的次数。
常见的时间复杂度
算法的空间复杂度
算法的空间复杂度通过计算算法所需的存储空间实现。
算法的空间复杂度的计算公式记作:
S(n)=O(f(n)),
其中,n为问题的规模,f(n)为语句关于n所占存储空间的函数。
现在的硬件发展速度之快使得我们完全可以不用考虑算法所占的内存,通常都是用空间换取时间。加之算法的空间复杂度比较难算,
所以,无论是在考试中还是在项目开发中,我们都侧重于时间复杂度。