购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.1.1 如何评价一个算法的优劣

算法是对特定问题求解步骤的一种描述,不依赖任何语言,可以用自然语言、C、C++、Java、Python等描述,也可以用流程图、框图来表示。同一个问题可以采用不同的算法解决。

那么怎样才算一个好算法呢?先看一个例子,写一个算法,求这个序列之和:-1,1,-1,1,…,(-1) n

看到这个题目时,你会怎么想?用for语句?还是用while循环语句?

先看算法sum1:

这段代码可以实现求和运算,但是为什么不这样算?

再看算法sum2:

假设 n =10 8 ,运行两个程序,比较一下运行结果和时间:

很明显,算法sum2的运行时间远远小于算法sum1,运行速度更快。

再看一个例子:假设第1个月有一对刚诞生的兔子,第2个月兔子进入成熟期,第3个月兔子开始生育兔子,而一对成熟的兔子每月会生一对兔子,兔子永不死去……那么,从一对初生兔子开始,12个月后会有多少对兔子呢? M 个月后又会有多少对兔子呢?

兔子数列即斐波那契数列,斐波那契数列的发明者是意大利数学家列昂纳多●斐波那契。这个数列有一个十分明显的特点:从第3个月开始,当月的兔子数=上月的兔子数+当月新生的兔子数,而当月新生的兔子数正好是上上月的兔子数,因此,前面相邻两项之和构成了后一项。即当月的兔子数=上月兔子数+上上月的兔子数。

斐波那契数列示例:1,1,2,3,5,8,13,21,34……

斐波那契数列表达式如下:

那么该如何设计算法呢?

按照数列表达式将其直接写成递归程序:

如果采用数组存储每一项,则从前往后递推,可以写成非递归程序。

两个程序的运行结果和时间如下:

两个程序的运行结果都正确,但是运行时间随着数据规模 n 的增大,差距越来越大。第1个程序计算到100的时候,已经非常缓慢了,缓慢到让人无法忍受,以至于将窗口关闭。

不知你是否发现,第2个程序在 n =10时,time2=3;在 n =30时,time2=2。当数值变大时,时间反而变少了!其实,同一台机器,每一次运行的时间都可能不同,更不必说在不同的机器上运行了。因此计算算法时间复杂度时并不是真的计算算法的运行时间。

好算法的衡量标准如下。

(1)正确性。指算法能够满足具体问题的需求,程序运行正常,无语法错误,能够通过典型的软件测试,达到预期需求规格。

(2)易读性。指算法遵循标识符命名规则,简捷、易懂,注释语句恰当、适量,方便自己和他人阅读,便于后期调试和修改。

(3)健壮性。指算法对非法数据及操作有较好的反应和处理。例如在信息管理系统中登记电话号码时,少输入1位,系统就应该提示出错。

(4)高效性。指算法运行效率高,即算法运行所消耗的时间短。算法时间复杂度就是算法运行需要的时间。现代计算机一秒钟能计算数亿次,因此不能用秒来具体计算算法消耗的时间。由于采用相同配置的计算机进行一次基本运算的时间是一定的,所以我们可以用算法基本运算的执行次数来衡量算法效率,即将算法基本运算的执行次数作为时间复杂度的衡量标准。

(5)低存储性。指算法所需的存储空间少。尤其像手机、Pad这样的嵌入式设备,如果算法占用空间过大,则无法运行。算法占用的空间大小被称为空间复杂度。

除前3条基本标准外,好算法的评判标准是高效率和低存储。 CSY+E1ImaKwJPUY9XJ+Y/KHb6m++ufc4OwiOGvvyme1SqmcSgYkm5iwnbfUTiNg4

点击中间区域
呼出菜单
上一章
目录
下一章
×