笔记:王道考研数据结构
什么是算法
程序 = 数据结构 + 算法
五个特性
有穷性: 一个算法必须总在执行有穷步之后结束,且每一步都可在有穷时间内完成。
注:算法必须是有穷的,而程序可以是无穷的
确定性: 算法中每条指令必须有确切的含义,对于相同的输入只能得出相同的输出。
可行性: 算法中描述的操作都可以通过己经实现的基本运算执行有限次来实现
输人: 一个算法有念个不或多个输人,这些输入取自于某个特足的对象的集合。
输出: 一个算法有二个或多个输出,这些输出是与输入有着某种特定关系的量。
好算法的特质
正确性: 就是要对
可读性:能让别人看懂
健壮性: 输入非法的数据时,能够做出错误反应
高效率与低存储量需求
高效率: 执行速度快,时间复杂度低
低内存: 不费内存,空间复杂度低
时间复杂度
存在什么问题?
和机器性能有关,如:超级计算机V.s.单片机
和编程语言有关,越高级的语言执行效率越低
和编译程序产生的机器指令质量有关。
事前预估算法时间开销T(n)与问题规模n的关系(T表示“time”)
EG:
可以只考虑阶数高的部分,简化成o(n)
a)加法规则(多项相加,只保留最高阶的项,且系数变为1)
T(n)=Ti(n)+T2(n)=O(f(n))+o(g(n))=O(max(f(n),g(n)))
b)乘法规则(多项相乘,都保留)
T(n)=T(n)×T2(n)=Ofn)×O(gn)=Ofn)Xgn)
Eg:
T3(n) = n^3 + n^2 log2n
= O(n^3) + O(n^2 logzn)
比较: O(1)<O(log2n)<O(n)<O(nlog2n)<O(n2)<O(n3)<O(2)<O(n!)<O(n")
口诀:常对幂指阶
结论1:顺序执行的代码只会影响常数项,可以忽略
结论2:只需挑循环中的一个基本操作分析它的执行次数与n的关系即可
结论3:如果有多层嵌套循环,只需关注最深层循环循环了几次
空间复杂度
int a; //S(n) = O(1)
int a[n]; //S(n) = O(n)
int a[n][n]; //S(n) = O(n^2)
加法规则
T(n) = Ti(n) + T2(n) = o(f(n)) + o(g(n)) = O(max(f(n), g(n)))
乘法规则
O(f(n)×O(g(n)=O(f(n)×g(n)
比较
O(1) < O(log2n) < O(n) < O(nlog2n) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)
常对幂指阶
函数的递归带来的内存开销
空间复杂度=递归调用的深度