1、算法(Algorithm)的定义
目前普遍认可的对算法的定义为:算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。
2、算法的特性
算法具有五个基本特性:输入、输出、有穷性、确定性和可行性。
2.1 输入输出
- 输入:算法具有零个或者多个输入
- 输出:算法至少有一个输出(不存在没有输出的算法,这样的算法没有意义)
2.2 有穷性
算法在执行有限的步骤之后,自动结束而不会出现无限循环,并且每一个步骤在可接受的时间内完成。
notes:有穷的概念并不是一个纯数学意义上的,而是实际应用中合理的、可接收的有边界。
2.3 确定性
算法的每一个步骤都具有确定的含义,不能出现二义性。
2.4 可行性
算法的每一步都必须是可行的,也就是说,每一步都是能够通过执行有限次数完成。·
2.3 算法设计的要求
一个好的算法应该满足四个层次条件:正确性,可读性,健壮性,时间效率高和存储量低。
2.3.1 正确性
正确性是算法的基本要求。要求算法至少应该具有输入、输出和加工处理无歧义性、能够正确反映问题的需求、能够得到问题的正确答案。一个算法的有正确性,可从以下四个层次分析:
1、算法程序没有语法错误。
2、算法程序对合格的输入数据能够产生满足要求的输出结果
3、算法程序对于非法的输入数据能够得到满足规格说明的结果
4、算法程序对于精心选择的,甚至刁难的测试数据都有满足要求的输出结果
证明一个算法在所有层次都是正确的是很困难的,尤其是层面四,几乎不可能逐一验证所有的输入是否能得到正确的结果。
2.3.2 可读性
可读性:算法设计的另一个目的就是为了便于阅读、理解与交流。
Notes:可读性是算法(也包括实践它的代码)好坏很重要的标识。
2.3.3 健壮性
健壮性:当输入数据不合法时,算法也能够做出相关处理,而不是产生异常或者莫名其妙的结果。
2.3.4 时间效率高和存储量低
时间效率指的是算法的执行时间,对于同一个问题,执行时间短的算法更优。
存储量指的是算法执行过程中需要的最大存储空间,主要是算法程序运行时所占用的内存或外部硬盘存储空间。
2.4 算法效率的度量方法
算法的效率可以通过两种方法估算:
1、事后统计方法
2、事前分析估值方法
2.4.1 事后统计方法
主要通过设计好测试程序和数据,利用计算机计时器对不同算法编制的程序的运行时间进行比较,从而确定算法效率的高低。
缺点:
1、依据算法编制程序会耗费大量时间和精力,而且万一这算法不可行,那就是白编写半天了。
2、时间的多少会依赖计算机的硬件条件。
3、算法的测试数据设计困难,并且程序的运行时间与测试数据的输入规模有很大关系,采用多大规模的数据来测试往往很难抉择。
由于以上确定,算法的估算并不采用事后统计方法。
2.4.2 事前分析估算方法
在计算机程序编制前,依据统计学方法对算法进行估算。这也是今后分析算法优越的方法
程序在计算机上运行时所消耗的时间一般取决于以下因素:
1、算法采用的策略、方法。
2、编译产生的代码质量。
3、问题的输入规模。
4、机器执行指令的速度
其中第二条需要软件来支持,第四条与硬件相关。那么除去软硬件相干因素,一个程序的运行时间,依赖于算法的好坏和问题的输入规模。
对于同一计算机而言,每条基本语句执行的时间是一样的,那么,测试运行时间最可靠的方法就是计算对运行时间有消耗的基本操作的执行次数。所以,在分析程序的运行时间时,最重要的是把程序看成独立于程序设计语言的算法或者一系列步骤。
2.5 函数的渐近增长
给定两个函数f(n)和g(n),如果存在一个整数N,使得对于所有的n>N,f(n)总是比g(n)大,那么,我们说发f(n)的增长渐近快于g(n)
判断一个算法的效率时,函数中的常数和其他次项常常可以忽略,更应该关注最高阶项。
2.6 算法时间复杂度
2.6.1 时间复杂度定义
在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析T(n)随n的变化情况并确定T(n)的数量级·。
2.6.2 常见的时间复杂度
其中只有当代码块2中的10000变成n时,才是O(n),否则为O(1)。而对于平方,立方,nlogn都可以通过上述组合得到,所以不再介绍。
2.6.3 master定理介绍与证明
2.6.4 最坏情况与平均情况
查找一个有n个随机数字数组中的某个数字:
最好的情况:第一个数字就是,算法的时间复杂度为O(1),
最坏的情况:数字在最后一个位置上,算法的时间复杂度就是O(n)
最坏情况运行时间是一种保证。在应用中,这是一种最重要的需求, 通常,除非特别指定,我们提到的运行时间都是最坏情况的运行时间
平均运行时间:所有情况中最有意义的,因为它是期望的运行时间。
但平均运行时间很难通过分析得到,一般都是通过运行 一定数量的实验数据后估算出来的。