目录
一、 算法概述
1.什么是算法?
算法(algorithm):算法是对特定问题求解步骤的描述,是指令的有限序列。就是定义良好的计算过程,他取一个或一组的值为输入,并产生出一个或一组值作为输出。简单来说算法就是一系列的计算步骤,用来将输入数据转化成输出结果。
2.算法的五个特征
- 输入:算法有零个或多个输入量;
- 输出:算法至少产生一个输出量;
- 确定性:算法的每一条指令都有确切的定义,没有二义性;
- 可行性:算法的每一条指令必须足够基本,它们可以通过已经实现的基本运算执行有限次来实现;
- 有穷性:算法必须执行有限步之后终止。
3.问题和问题求解
问题求解:寻找一种方法来实现目标。
问题求解过程:人们通过使用问题领域知识来理解和定义问题,并凭借自身的经验和知识求选择和使用适当的问题求解策略、技术和工具,将一个问题描述转换成问题解的过程。
计算机求解问题的关键之一是寻找一种问题求解策略得到求解问题的算法,从而得到问题的解。
4.问题求解过程
- 理解问题
- 设计方案
- 实现方案
- 回顾复查
二、 算法分析
1. 算法求解过程
2.算法分类
- (Non-) Numerical: 这指的是算法是否处理数值数据。数值算法通常用于解决数学问题,如计算、优化等。非数值算法则可能处理文本、图像或其他非数值类型的数据。
- Strategically: 指的是算法在解决问题时所采取的策略。这可以包括算法的设计、选择和应用,以及如何根据特定问题调整算法以获得最佳性能。
- Complexity: 这涉及到算法的复杂性,通常指的是算法的时间复杂度和空间复杂度。时间复杂度描述了算法执行时间随输入规模增长的变化,而空间复杂度描述了算法所需的存储空间。
- Exactness: 这指的是算法提供的解决方案的精确度。有些算法可能提供精确解,而有些算法可能只提供近似解,这取决于问题的性质和算法的设计。
- (Non-) Deterministic: 这描述了算法的确定性。确定性算法在给定相同的输入时总是产生相同的输出。非确定性算法则可能在相同的输入下产生不同的输出,这通常与随机性或并行计算有关。
- Application Orientated: 这表明算法是为了解决特定应用领域的问题而设计的。应用导向的算法会针对特定类型的数据或问题进行优化。
几种算法分类:
- 精确算法总能保证求得问题的解。
- 启发式算法通过使用某种规则、简化或智能猜测来减少问题求解时间。
- 近似算法:对于最优化问题,一个算法如果致力于寻找近似解而不是最优解,被称为近似算法。
- 随机算法:如果在算法中需要做出某些随机选择,则称为随机算法。
3.算法设计
- 计算机的问题求解策略主要指算法设计策略。
- 如果所求问题符合某种算法设计策略处理问题的特性,就可使用该算法设计策略设计算法、求解问题。
4.算法分析
为什么要分析算法:改进算法;为一个问题选择合适的算法
从以下几个方面分析算法:
- Correctness(正确性): 这是评估算法是否能够正确解决问题的标准。一个正确的算法应该能够对所有合法的输入数据产生正确的输出结果。
- Amount of work done(工作量): 这涉及到算法执行所需的计算工作量。通常通过时间复杂度来衡量,即算法执行时间随输入规模增长的变化。工作量越少,算法效率越高。
- Amount of space used(空间使用量): 这指的是算法在执行过程中所需的存储空间。空间复杂度描述了算法所需的存储空间随输入规模增长的变化。空间使用量越少,算法在资源受限的环境中越有优势。
- Simplicity(简洁性): 这涉及到算法的复杂度和易读性。一个简洁的算法更容易理解和实现,也更容易维护和调试。
- Optimality(最优性): 这指的是算法是否能够以最有效的方式解决问题,即在给定问题的所有可能算法中,是否达到了最佳的时间复杂度或空间复杂度。最优算法在资源使用上是最节省的。
程序健壮性:是指当输入不合法数据时,程序可以做适当处理而不至于引起严重后果。 其含义是:当程序万一遇到意外时,能按某种预定方式作出适当处理。
正确性和健壮性是相互补充的。
5.时间复杂度
影响程序时间的因素:(a)程序所依赖的算法;(b)问题规模和输入数据规模;©计算机系统的性能。
5.1 最好,最坏,平均时间复杂度
同一段代码,在不同输入的情况下,复杂度量级有可能是不一样的。所以为了更细化的分析算法的复杂度在复杂度分析方面引入4个知识点:最好、最坏、平均、均摊时间复杂度。假设对于每种输入
I
I
I,需要的时间为
t
(
I
)
t(I)
t(I),则最好、最坏、平均时间复杂度计算如下:
B
(
n
)
=
min
I
t
(
I
)
W
(
n
)
=
max
I
t
(
I
)
A
(
n
)
=
∑
I
p
(
I
)
t
(
I
)
B(n)=\min _{I} t(I) \\W(n)= \max_{I} t(I) \\A(n)=\sum_{I}p(I)t(I)
B(n)=Imint(I)W(n)=Imaxt(I)A(n)=I∑p(I)t(I)
5.2 Big-oh
通常情况下,最好、最坏、平均时间复杂度之间只差一个系数和常量,因此可以用Big-oh表示。
T
(
n
)
=
O
(
f
(
n
)
)
T(n)=O(f(n))
T(n)=O(f(n))
其中,
lim
n
→
无穷
T
(
n
)
O
(
n
)
≤
c
\lim_{n \rarr 无穷} \frac{T(n)}{O(n)}\le c
n→无穷limO(n)T(n)≤c
Big-oh的运算:
O
(
f
(
n
)
)
+
O
(
g
(
n
)
)
=
O
(
f
(
n
)
+
g
(
n
)
)
=
max
{
O
(
f
(
n
)
+
O
(
g
(
n
)
)
}
O
(
f
(
n
)
)
∗
O
(
g
(
n
)
)
=
O
(
f
(
n
)
∗
g
(
n
)
)
O
(
c
f
(
n
)
)
=
O
(
f
(
n
)
)
O(f(n))+O(g(n))=O(f(n)+g(n))=\max \{O(f(n)+O(g(n))\}\\ O(f(n))*O(g(n))=O(f(n)*g(n)) \\O(cf(n))=O(f(n))
O(f(n))+O(g(n))=O(f(n)+g(n))=max{O(f(n)+O(g(n))}O(f(n))∗O(g(n))=O(f(n)∗g(n))O(cf(n))=O(f(n))
5.3 渐近复杂度
渐近复杂度是分析算法效率的一种方式,它描述了算法运行时间或占用空间随输入规模增长的变化趋势。
-
Ο,读音:big-oh;表示上界,小于等于。
-
Ω,读音:big omega、欧米伽;表示下界,大于等于。
-
Θ,读音:theta、西塔;既是上界也是下界,称为确界,等于。
-
ο,读音:small-oh;表示上界,小于。
-
ω,读音:small omega;表示下界,大于。
Ο是渐进上界,Ω是渐进下界。Θ需同时满足大Ο和Ω,故称为确界。Ο极其有用,因为它表示了最差性能。
(1)大O表示法,表示时间复杂度的上界。
T
(
n
)
=
O
(
g
(
n
)
)
T(n)=O(g(n))
T(n)=O(g(n))
数学含义:存在一个正的常数
c
c
c和一个非负整数
n
0
n_0
n0,使得对于所有
n
≥
n
0
n\ge n_0
n≥n0,都有:
T
(
n
)
≤
c
g
(
n
)
T(n)\le cg(n)
T(n)≤cg(n)
- 与 T ( n ) T(n) T(n)相比, f ( n ) f(n) f(n)更为简洁,但依然会反映前者的增长趋势。
- 低次项可忽略。
(2)大Ω表示法,表示时间复杂度的下界。
T
(
n
)
=
Ω
(
g
(
n
)
)
T(n)=Ω(g(n))
T(n)=Ω(g(n))
数学含义:存在一个正的常数
c
c
c和一个非负整数
n
0
n_0
n0,使得对于所有
n
≥
n
0
n\ge n_0
n≥n0,都有:
0
≤
c
g
(
n
)
≤
f
(
n
)
0\le cg(n) \le f(n)
0≤cg(n)≤f(n)
(3)不同渐进时间复杂度之间的关系和运算:
6.空间复杂度
空间复杂度全称就是渐进空间复杂度(asymptotic space complexity),表示算法在运行过程中临时占用的存储空间大小的量度。包括两个部分:
- 固定空间需求:这部分空间与所处理数据的大小和个数无关,即与问题实例的特征无关。
- 指令空间(Instruction Space):程序中所有指令所占用的内存区域。
- 环境栈空间(Environment Stack Space):程序在执行过程中,用于存储函数调用和局部变量的内存区域。
- 可变空间需求:这部分空间大小与算法在某次执行中处理的特定数据的规模有关。
- 数据空间(Data Space):程序中所有数据(如变量、数组等)所占用的内存区域。
7.简洁性
通常(尽管并非总是如此),解决问题最简单和最直接的方法并不是最有效的。然而,算法的简洁性是一个理想的特性。
- 简洁性的好处:简洁的算法可能使得验证算法的正确性变得更容易,并且使得为算法编写、调试和修改程序变得更简单。
- 开发时间的考虑:在选择算法时,应该考虑生产一个经过调试的程序所需的时间。
- 效率的重要性:如果程序将被频繁使用,那么它的效率可能会成为选择算法的决定性因素。
8.最优性
-
**定义:**算法在最坏情况下的效率,即在所有可能的输入中,算法执行所需的基本操作数量最少。
-
比较基准:算法的最优性是通过与同一类别中的其他算法进行比较来确定的。
-
实际意义:一个在最坏情况下表现最优的算法,意味着无论输入如何,它都能保证一定的效率,这对于需要高可靠性的应用场景非常重要。
-
选择算法:在设计算法时,考虑其在最坏情况下的表现可以帮助确保算法的鲁棒性和效率。
如何证明一个算法是最优的:通过证明定理来确定解决问题所需的最小操作数量,这是一个下界。如果一个算法能够达到这个下界,那么它在最坏情况下是最优的。
三、算法开发
算法开发过程包括:
- 问题陈述(Statement of the problem)
- 模型开发(Development of a Model)
- 算法设计(Design of the algorithm)
- 算法正确性(Correctness of the algorithm)
- 实现(Implementation)
- 算法分析与复杂度(Analysis and complexity of the algorithm)
- 程序测试(Program testing)
- 文档编写(Documentation)
四、算法描述
1. 伪代码
用缩进表示逻辑结构