在我们遇到问题的时候,首先在大脑形成一种解题思路,然后根据可行的思路运用具体的步骤解决问题。在程序设计中,也需要有一种编程思路,这就是算法。
算法的概念
广义上的算法指的是解决问题的方法。就程序设计而言,算法是指计算机求解某一问题而采用的具体方法、步骤。事实上,在日常生活中解决问题经常要用算法,只是通常不用“算法”这个词罢了,例如,乐谱是乐队指挥和演奏的算法;菜谱是厨师做菜的算法,等等。
在程序设计中,算法应该能够离散成具体的若干个操作步骤,每一个步骤都是能够用程序设计语言提供的语句或者语句串来完成的。
例如,求两个整数中较大的数。解决这个问题的算法如下:
第1步 开始
第2步 输入两个整数a、b。
第3步 比较a,b的大小,如果a>b,输出a,否则输出b。
第4步 结束。
需要注意的是,程序是有开始和结束的,所以算法必须有“开始”和“结束”
计算机解题算法分为两大类:数值运算和非数值运算算法。数值运算算法解决的是求数值的问题,运用一定的求值公式如二元一次方程的求根公式、圆面积的计算公式等。这类算法相对比较成熟。非数值运算的算法涉及的内容比较广,而且难以量化,一般都需要参考已有的类似算法,针对具体问题重新设计。
算法的特点
解决问题我们需要一个可行的算法,而如何取衡量这个算法是否得当,是否可行呢?通常,算法具有以下5个重要的特征。
一个算法应包括有限个操作步骤,其中每一步都应在合理的时间范围内完成。有的可能要花很长的时间来执行指定的任务,但仍将在一定的时间内终止。执行的时间没有严格的限制,受所要处理问题的约束。
算法在指导计算执行每步程序时,这些指令都是明确的,没有任何歧义。例如:
输出:A/正整数
是无法执行的,因为正整数指的是一类数,没有指定A除以哪一个正整数,所以这个步骤是不确定的。
算法中的每个步骤都应该是由意义、能够有效执行的,并能得到确定的结果。比如,开方运算的数不能是负数:分母不能够为0。
一个算法有零个或多个输入。在某些算法中,所需要的数据可以由用户输入设备输入,例如,求两个数中的较大值,这两个数可以是用户随意输入的两个数,它们的值是不确定的。另外在编程的过程中也可以用两个确定的数进行比较,这时就不需要用户的输入,即零输入。
一个算法有一个或多个输出。算法的输出反映了输入数据加工后的结果,没有输出的算法是毫无意义的。例如:求两个数的最大公约数,执行后,若这两个数有最大公约数就输出,若没有最大公约数就输出“这两个数无最大公约数”给用户以反馈。
算法的表示方法
一个算法可以用多种不同的方法来描述,有自然语言、伪代码、N~S图等,每种表示方法都有自己的优缺点,可以根据不同的需要选择适当的表示方法。
1.自然语言
使用自然语言描述算法是指用文字加上一些必要的数字符号来描述解决问题的算法。
【实例1-6】用自然语言描述100以内正整数的和。
自然语言表示法,除了很简单的问题外,一般不用这种方法。从上面的例子中我们不难发现,自然语言容易理解,也比较容易掌握,但需要用大量的文字进行解释说明不直观。当算法中含有多分支或循环操作时很难表述清楚。
2.流程图
流程图很好地弥补了自然语言描述算法的缺陷,它用标准的图形元素来描述算法步骤,程序结构一目了然。流程图最基本、最常用的构件如下所示:
符号 |
名称 |
用途 |
开始,结束符 |
用来表示程序的开始和结束。一个算法只能有一个开始处,但可以有多个结束处 |
|
输入,输出框 |
表示数据的输入和计算数据的输出 |
|
处理框 |
表示需要处理的内容,只有一个入口和一个出口 |
|
判断框 |
用来表示分支情况,菱形框的四个顶点中,通常用上方的顶点表示入口,视需要用其余两个顶点来表示出口 |
|
流程线 |
指出流程控制的方向,即动作的次序 |
算法从“开始”执行,依次按照流程顺序执行了前四个输入框内的动作,到达判断框后先判断N是否满足条件,如果条件成立,即判断的结果为True(简写为T),沿着T所示的流程返回到第三步开始继续执行,如果判断条件不成立,即判断的结果为False(简写为F),沿着F所示的流程线向下执行,最后输出S。
使用流程图来描述算法比较自由灵活,形象直观,可以用来表示任何算法,但是绘制流程图之前要弄清哪些是判断的条件,哪些是处理的操作,而且绘图也比较麻烦,并且用箭头表示程序流程的方向,随意性太大。
3.伪代码
伪代码是一种在算法开发过程中用来表达思想的非形式化的符合系统。相对于编程语言来说,它的语法规则、语义结构等规定限制比较宽松,是一种更加易用的 表示系统。
将【实例1-6】用伪代码描述表示如下:
1Nß1;
2Sß0;
3do while N<=100
4{SßS+N;
NßN+1}
5print S
伪代码通常采用自然语言、数学公式和符合描述算法的操作步骤,同时采用计算机高级语言的控制结构来描述算法步骤的执行顺序。但前提是必须熟悉某种程序设计语言,软件专业人员一般习惯使用伪代码。
4.N-S图
N-S图也被称为盒图。在使用流程图的过程中,人们分析流程线不一定是必需的,为此,又设计出了一种新的流程图,把整个程序写在一个大框图内,这个大框图由若干个小基本框图构成,这种流程图简称为N-S图。
在结构化程序设计中,用N-S图表示顺序结构、选择结构和循环结构的结构有所不同,具体表示如下:
如图1-2中的顺序结构图所示,程序执行的顺序按照矩形块出现的顺序从上向下依次执行,先执行A块再执行B块。
(2) 选择结构N-S图
如图1-2中的选择结构图所示,程序执行到此步时,先判断条件的真假,如果为真就执行A块,如果为假就执行B块
(3) 循环结构N-S图
如图1-2中的循环结构图所示,循环结构的N-S图有两种结构,一种是当型循环,一种是直到型循环。当型循环指的是先判断条件,如果条件为真就执行循环体,否则就跳过循环体执行下面的程序。直到型循环指的是先执行一次循环体,然后再判断条件,如果条件为真就返回继续执行循环体,否则就不执行循环体,开始向下执行。
将【实例1-6】用N-S图描述表示如图1-3所示。
N-S图弥补了流程图自由性大、任意转移控制的缺点,表示嵌套关系方便直观,对模块和控制结构的层次和作用域显示行比较清晰;但是N-S图修改起来没有流程图方便,如果分支嵌套层次一多就比较难画了。
算法分析
算法分析是对一个算法需要多少计算时间和存储空间做定量的分析。求解一个给定的可计算或可解的问题,不同的人可以编写出不同的程序,分析算法可以预测这一算法适合在什么样的环境中有效地运行,对解决同一问题的不同的算法的有效性做出比较。
什么样的算法才是一个好的算法呢?通常从下列几个方面衡量算法的优劣。
也称为有效性,是指算法能满足具体问题的要求。即对任何合法的输入,算法都会得出正确的结果。确认正确性的根本方法是进行形式化的证明。但对一些较复杂的问题,这是一件相当困难的事。许多计算机科学工作者正致力于这方面的研究,目前尚处于初级阶段。因此,实际中常常用测试的方法验证算法的正确性。
值算法被理解的难易程度。人们常把算法的可读性放在比较重要的位置。主要是因为晦涩难懂的算法不易交流和推广使用,也难以修改、扩展与调试,而且可能隐藏较多的错误。
即对非法输入的抵抗能力。它强调的是,如果输入非法数据,算法应能加以识别并做出处理,而不是产生错误动作或陷入瘫痪。
算法的时间复杂度指算法需要消耗的时间资源,也就是说算法的运行时间。一般来说计算机算法是问题规模n的函数f(n),算法的时间也因此记为:T(n)=O(f(n))
因此,问题的规模越大,算法执行的时间的增长率与f(n)的增长率正相关,称为渐进时间复杂度。
算法的空间复杂度是指算法需要消耗的空间资源。其计算和表示方法与时间复杂度类似,一般都用复杂度的渐进性来表示。记为:S(n)=O(f(n))