(一)什么是算法?——算法设计与分析

144 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情


一、基本定义

1.1 计算的定义

可由一个给定计算模型机械地执行的规则或计算步骤序列称为该计算模型的一个计算。

注意:

  • 计算可能永远不停止(区别于算法)
  • 一个计算机程序是一个计算(计算模型是计算机)

1.2 算法的定义

算法是一个满足下列条件的计算:

有穷性/终止性:有限步内必须停止

确定性:每一步都是严格定义和确定的动作

能行性:每一个动作都能够被精确地机械执行

输入:有一个满足给定约束条件的输入

输出:满足给定约束条件的结果


1.3 问题的定义

InputInputOutputOutput是两个集合。

一个问题是一个关系RInput×OutputR\subseteq Input\times OutputInputInput称为问题RR的输入集合,InputInput的每个元素称为RR的一个输入,OutputOutput称为问题RR的输出或结果集合,OutputOutput的每个元素称为RR的一个结果。

问题定义了输入和输出的关系。一个算法面向的是一个问题,而不是仅仅求解问题的一个或者几个实例。(说人话就是,算法是一类问题的通解)


二、算法分析

2.1 正确性分析

2.1.1 正确性

算法的正确性:如果一个算法对于每一个输入都最终停,而且产生正确的输出,那么我们认为该算法是正确的。

相应地,不正确算法有两种情况:①不停止;②输出结果错误。

类似地,定义近似算法:①对所有输入停止;②输出结果近似正确,或者错误量少。


2.2.2 循环不变量

(1)定义

循环不变量方法是证明主要结构为循环结构的算法正确性的方法。

循环不变量:数据或者数据结构的关键性质,依赖于具体算法。

(2)证明方法:

初始时:循环开始前,循环不变量成立

循环中:循环体每执行一次,循环不变量成体

终止后:算法结束后,循环不变量保证算法正确

以插入排序为例:

//Insertion-sort(A)
for j=2 to n do:
	key = A[j]
	i = j-1
	while i>0 and A[i]>key do
		A[i+1] = A[i]
		i = i-1
A[i+1] = key

其中:

循环不变量为:A[1, 2,...,j-1]来自输入且有序

初始时,j=2j=2,循环不变量成立(A[1]A[1]来自输入且有序)

循环时:循环不变量成立(A[1,2,...,j1]A[1, 2,...,j-1]来自输入且有序)

终止后:j=n+1j=n+1,循环不变量成立,且保证算法正确(A[1,2,...,n]A[1,2,...,n]来自输入且有序,并且使得数组达到了排序的目的)


2.2 复杂性分析

复杂性分析用于预测算法对于不同输入所需要的资源量。一般分为时间复杂度和空间复杂度,并称时空复杂度。

具体如何求解时空复杂度将在以后讲解,这里给出定义。


2.2.1 时间复杂度

(1)定义

该算法对于给定输入,求解问题所需的原子操作的步数。

一般有最好时间复杂度、最坏时间复杂度、平均时间复杂度。对于一些含有随即性质的算法,还会有期望复杂度等。

注意:

①时间复杂度是输入大小的函数;

②即使实际上每步需要的时间量不同,但我们仍假设执行每一步所需要常数时间。


2.2.2 空间复杂度

(1)定义

该算法对该输入产生结果所需要的额外存储空间大小。


2.2.3 复杂度的分类

InputInput是问题RR的输入集合,Complexity(X)Complexity(X)是求解RR的算法AA的复杂度函数,Size(y)Size(y)是问题输入大小的函数。

(1)最坏(大)复杂度

Max{Complexity(Size(y))yInput}Max \left \{ Complexity(Size(y))\mid y\in Input\right \}

(2)最好(小)复杂度

Min{Complexity(Size(y))yInput}Min \left \{ Complexity(Size(y))\mid y\in Input\right \}

(3)平均复杂度

yInputpy×Complexity(Size(y))\sum_{y\in Input}p_y\times Complexity(Size(y))

其中,pyp_y是任意yy作为输入的概率