算法和算法评价

算法的基本概念

算法:对特定问题求解步骤的一种描述,它是指令的有限序列,其中的每条指令表示一个或多个操做。算法

根据以上定义,能够知道,算法必定是能够解决特定问题的,其次,它是有限的,而后,每个指令都表示特定的操做。因而能够知道算法的五个特性:学习

  • 有穷性:一个算法必须在执行有穷步以后结束,且每一步都必须在有穷时间内完成。若是有相似无限循环的语句,那么就不能称之为算法。
  • 可行性:一个算法是可行的,即算法中描述的操做都是能够经过已经实现的基本运算执行有限次来实现的。每一步操做都是能够实现的才能称之为算法。
  • 肯定性:算法中每条指令、每条语句必须有确切的含义,相同的输入必须得出到相同的输出,不能产生二义性。
  • 输入:一个算法必须有零个或多个输入。
  • 输出:一个算法必须有一个或多个输出。

算法为何是有穷的?在操做系统中使用了不少无穷的代码语句,它们也是很是有用的,它们不是算法,那它们又是什么?对此,引入一个程序的概念,什么是算法,什么又是程序操作系统

根据上面的算法的定义,能够知道,算法是解决问题的一种方法或一个过程,例如如何将输入转换成输出。一个问题能够有不少不一样的算法。而程序是某种程序设计语言对算法的具体实现。咱们能够用 C 语言来编写,也能够用 Python 语言来编写,只要是在计算机内部运行的程序设计语言均可以。这是对算法和程序的简单描述。咱们发现,算法更像一个解决问题的 “指导者”,而程序更像一个具体实现的 “实施者”,能够利用算法来指导程序的编写和实施。设计

算法和程序主要有三方面的区别:code

  • 有穷性:算法必须是有穷的,程序能够是无穷的,因此在操做系统中,那些颇有用的,但又无限循环的,能够 称之为程序。
  • 正确性:算法必须是正确的,程序能够是错误的。设计出的算法必须正确的来解决问题,而程序能够编写错误而后进行修改。
  • 描述方法:算法能够用伪代码、程序语言、天然语言、程序框图等描述,程序只能用程序设计语言编写并能够运行。

算法效率的度量

如何设计一个 "好" 的算法?blog

首先一个好的算法必须具备正确性,应该可以正确的解决问题。算法是一个 “指挥者”,若是一个 “指挥者” 不能正确的指导 “实施者” 去实施,那么它必定不是一个好的算法。程序设计

第二个是可读性。算法应具备良好的可读性,以帮助人们理解。在人们修改阅读算法时,人们应可以快速的理解掌握该算法。class

第三个是健壮性。健壮性是指在输入非法数据时,算法能适应的作出反应或进行处理。效率

最后一个是效率与存储量需求。效率是指算法执行时间,存储量需求是指算法执行过程当中所需最大存储空间。这是最经常使用的用来考量一个好的算法的标准。也就是时间复杂度空间复杂度变量

时间复杂度

在学习时间复杂度以前,先掌握两个概念:语句的频度T(n)

语句频度:该条语句可能重复执行的次数

T(n):全部语句的频度之和,其中 n 为问题的规模

int sum = 0;
for(int i=1; i<=n; i++)
    sum += i;

第一句是初始化 sum 为 0,它的语句频度是 1,由于它只被执行了一次。第二个是循环体中的语句 sum += i ,根据它的判断条件,能够知道它执行了 n 次,因此该条语句的语句频度是 n。那么该段代码的语句频度之和就是 T(n)=1+n

时间复杂度:记做 T(n) = O(f(n)) ,其中 O 表示 T(n)f(n) 在 n 趋向于正无穷时为同阶无穷大,能够把 f(n) 理解为某一个数量级或者是当 n 趋于正无穷时的一种增加率。

根据同阶无穷大的知识,能够知道:

因此说,它的 f(n)=n ,它的时间复杂度为 O(n)

时间复杂度有三种分类:最坏时间复杂度、最好时间复杂度、平均时间复杂度

int sum = 0;
if(n != 0)
    for(int i=1; i<=n; i++)
        sum += i;

这段代码中,若是 n 不等于 0 ,它的 T(n) = 1 + n,它的时间复杂度为 O(n) ,若是当 n 等于 0 ,它仅仅执行了第一条语句,也就是说它的 T(n) = 1,则它的时间复杂度为 O(1) 。因此说在不一样的判断中,时间复杂度是不一样的,因此有最坏和最好之分,平均时间复杂度就是在全部输入的几率的状况下,求一个时间复杂度的指望值。

在分析一个算法时, 每每会使用最坏时间复杂度,这个是最具备实际意义的。

学习了时间复杂度的分类后,来看一下时间复杂度在运算上有怎样的规则。

加法规则:当对两个时间复杂度进行求和运算时,能够将较大数量级的代码的时间复杂度做为它们的和,能够经过同阶无穷大来进行验证

乘法规则:两个时间复杂度的乘积可使它先对数量级进行乘积再求同阶无穷大

一般采用基本运算频度来分析算法时间复杂度,基本运算频度也就是指最深层的循环语句的频度。

int sum = 0;
for(int i=1; i<=n; i++)
    sum += i;
for(int i=1; i<=n; i++)
    for(int j=1; j<=n; i++)
        sum += i;

这段代码中,第一句的语句频度是 1,而后第三句循环执行 n 次,语句频度是 n,第四句第五句是一个双层循环,而且都是循环 n 次,所以它的语句频度是 n2 ,因此这段代码的 T(n) = 1 + n + n2 。根据加法规则,它的时间复杂度是 O(n2) 。它的最深层的循环语句的时间复杂度为 O(n2) ,采用基本运算频度来分析算法时间复杂度,也能够得出它的时间复杂度是 O(n2) 。

常见时间复杂度

空间复杂度

算法的空间复杂度是指算法消耗的存储空间,记做 S(n) = O(g(n)) ,O 表示同阶无穷大,g(n) 表示数量级,n 表明问题规模。

在计算算法空间复杂度时,要注意一点,就是什么是消耗的存储空间,它是除自己所用的指令、常数、变量和输入数据外的辅助空间。

算法原地工做时指算法所需辅助空间为常量,记做 O(1)

总结

相关文章
相关标签/搜索