基本概念
程 序 = 数 据 结 构 + 算 法 程序 = 数据结构 + 算法 程序=数据结构+算法
数据结构:如何把现实世界的问题信息化,将信息存进计算机。同时还要实现对数据结构的基本操作。
算法:如何处理这些信息,以解决实际问题
算法的特性
有穷性:一个算法必须总在执行有穷步之后结束,且每一步都可在有穷时间内完成。
算法必须是有穷的,而程序可以是无穷的
确定性:算法中每条指令必须有确切的含义,对于相同的输入只能得出相同的输出。
可行性:算法中描述的操作都可以通过已经实现的基本运算执行有限次来实现。
输入:一个算法有零个或多个输入,这些输入取自于某个特定的对象的集合。
输出:一个算法有一个或多个输出,这些输出是与输入有着某种特定关系的量。
“好”算法的特质
- 正确性:算法应能够正确地解决求解问题
- 可读性:算法应具有良好的可读性,以帮助人们理解(算法可以用伪代码描述,文字描述,重要的是要“无歧义”描述出解决问题的步骤)
- 健壮性:输入非法数据时,算法能适当地作出反应或者进行处理,而不会产生莫名其妙的输出结果
- 高效率(执行速度快,时间复杂度低)与低存储量需求(不费内存,空间复杂度低)
时间复杂度
事前预估算法是时间开销 T ( n ) T(n) T(n)与问题规模 n n n的关系
结论
- 一个算法的时间表达式,只保留阶数高的部分;
- 顺序执行的代码只会影响常数项,可以忽略;
- 只需挑循环中的一个基本操作分析它的执行次数与n的关系即可;
- 如果有多层嵌套循环,只需关注最深层循环循环了几次
三种复杂度
一般只考虑最坏时间复杂度和平均时间复杂度,最好时间复杂度的参考意义不大。
- 最坏时间复杂度:最坏情况下算法的时间复杂度
- 平均时间复杂度:所有输入示例等概率出现的情况下,算法的期望运行时间
- 最好时间复杂度:最好情况下算法的时间复杂度
常见时间复杂度比较:常对幂指阶
O
(
1
)
<
O
(
l
o
g
2
n
)
<
O
(
n
)
<
O
(
n
l
o
g
2
n
)
<
O
(
n
2
)
<
O
(
n
3
)
<
O
(
n
!
)
<
O
(
n
n
)
O(1) < O(log_2 n) < O(n) < O(nlog_2 n) < O(n^2) < O(n^3) <O(n!) < O(n^n)
O(1)<O(log2n)<O(n)<O(nlog2n)<O(n2)<O(n3)<O(n!)<O(nn)
空间复杂度
空间开销(内存开销)与问题规模n之间的关系。
无论问题规模怎么变,算法运行所需要的内存空间都是固定的常量,算法空间复杂度为
S
(
n
)
=
O
(
1
)
S(n) = O(1)
S(n)=O(1)
只需关注存储空间大小与问题规模相关的变量,算法空间复杂度为
S
(
n
)
=
O
(
n
)
S(n) = O(n)
S(n)=O(n)
规则
加法规则:
函数递归调用带来的内存开销