
1.3.3 算法及算法的表示
初学者常常会有这样的一种感觉:读别人编写的程序比较容易,自己编写程序解决问题时就难了,虽然学了程序设计语言,可还是不知从何下手。其中一个重要的原因就是没有掌握程序设计的灵魂——算法。所以,请读者一定要重视算法的设计,多了解、掌握和积累一些计算机常用的算法,养成编写程序前先设计好算法的习惯。
1.算法的概念
尽管计算机可以完成许多极其复杂的工作,但实质上这些工作都是按照人们事先编好的程序的规定进行的,所以人们常把程序称为计算机的灵魂。著名的计算机科学家Niklaus Wirth提出了一个著名的公式:
程序=算法+数据结构
这个公式说明:对于面向过程的程序设计语言而言,程序由算法和数据结构两大要素构成。其中,数据结构是指数据的组织和表示形式,C语言的数据结构是以数据类型形式描述的;而算法就是进行操作的方法和操作步骤。这里重点讨论算法。
所谓算法,简单地说,就是为解决一个具体问题而采用的确定的、有限的操作步骤。这里所说的算法仅指计算机算法,即计算机能够执行的算法。
编写程序的关键是合理地组织数据和设计算法。如同去一个地方可能会有多条路线一样,解决一个问题也会有多种算法。因此,要想开发出高质高效的程序,除了要熟练掌握程序设计语言这种工具和必要的程序设计方法以外,更重要的是要多了解、多积累并逐渐学会自己设计一些好的算法。
设计一个算法后,怎样衡量它的好坏呢?一般地,可用如下特性来衡量:
①有穷性。算法包含的操作步骤是有限的,每一步都应在合理的时间内完成。
②确定性。算法的每个步骤都应是确定的,不允许有歧义。例如,“如果x大于等于0,则输出1;如果x小于等于0,则输出-1”。执行时,当x=0时,既输出1,又输出-1,这就产生了不确定性。
③有效性。算法中的每个步骤都应是能有效执行的,且能得到确定的结果。例如,对一个负数取对数,就是一个无效的步骤。
④有零个或多个输入。有些算法无须从外界输入数据,如计算10!;而有些算法需要输入数据,如计算n!,n的值是未知的,执行时需要从键盘输入n的值后再计算。
⑤有一个或多个输出。算法的实现是以得到计算结果为目的的,没有任何输出的算法没有任何意义。
2.算法的描述
了解算法的概念后,读者关心的下一个问题自然就是如何表示算法了。进行算法设计时,可以使用不同的算法描述工具,常用的有流程图、N-S图、自然语言、计算机语言、伪代码等。
(1)流程图
流程图(flow chart)是一种流传很广的描述算法的方法。这种方法的特点是用一些图框表示各种类型的操作,用带箭头的线表示这些操作的执行顺序。美国国家标准学会(ANSI)规定了图1-12所示的符号作为常用的流程图符号。
“两数中取大数”的流程图如图1-13所示。从图中可以看出,用流程图描述算法的优点是形象直观,各种操作一目了然,不会产生歧义性,便于理解,算法出错时容易发现,并可直观转化为程序;其缺点是所占篇幅较大,由于允许使用流程图,过于灵活,不受约束,用户可使流程任意转向,从而造成程序阅读和修改上的困难,不利于结构化程序的设计。

图1-12 常用的流程图符号

图1-13 “两数中取大数”的流程图
(2)N-S图
灵活的流线可能会导致程序中出现安全隐患。针对流程图这一弊病,美国学者L.Nassi和B.Schneiderman于1973年提出了一种无流线的结构化流程图形式,简称N-S图。Chapin在1974年对其进行了进一步扩展,因此N-S图又称Chapin图或盒状图。
N-S图的最重要特点就是完全取消流程线,使得算法只能从上到下顺序执行,不允许有随意的控制流,从而避免了算法流程的任意转向,保证了程序的质量。N-S图全部算法写在一个矩形框内。N-S图的另一个优点就是直观形象,比较节省篇幅,尤其适合于结构化程序的设计,因而很受欢迎。

图1-14 “3个数中取最大数”的N-S图
用N-S图描述的“3个数中取最大数”的算法如图1-14所示。
(3)自然语言
自然语言(natural language)就是人们日常生活使用的语言。用自然语言描述算法时,可使用汉语、英语和数学符号等。其比较符合人们日常的思维习惯,通俗易懂,初学者容易掌握。但其描述文字显得冗长,在表达上容易出现疏漏,并引起理解上的歧义性,不易直接转化为程序。所以,一般适用于算法比较简单的情况。
现假设待描述的问题是:在一组数中找出最大数。
首先分析此问题,并设计解决问题的算法,用自然语言描述如下:
①输入一组数。
②令第一个数为最大数并存入max中。
③将max与其余各数逐一进行比较。
a.若发现有大于max的数存在,则令其为新的最大数再次存入max中,然后重复③。
b.若没有发现大于max的数存在,那么max中所存放的数就是这组数中的最大值,转入④。
④输出最大数max。
⑤算法结束。
(4)计算机语言
目前,有许多算法是用计算机语言描述的,如Pascal,C/C++,VC++,Java等。例如:

(5)伪代码
伪代码是指用介于自然语言和计算机语言之间的一种文字和符号,它如同写文章一样,自上而下地写下来,每一行(或几行)表示一个基本操作。它不用图形符号,不能在计算机上运行,但是使用起来比较灵活,无固定格式和规范,只要写出来自己或别人能看懂即可。由于它与计算机语言比较接近,因此易于转换为计算机程序。
例如,“输出x的绝对值”的算法可以用伪代码表示如下:

它好像一个英语句子一样易懂,在西方国家用得比较普遍。也可以用汉字伪代码,例如:
若x为非负数(正数)输出x
否则输出-x
也可以中英文混用。
(6)其他算法描述方法
除了上述介绍的算法描述方法外,还可以用PAD图(问题分析图)描述算法。PAD图也没有流线,但有规则地安排了二维关系:从上到下表示执行顺序,从左到右表示层次关系。
在以上几种表示算法的方法中,具有熟练编程经验的专业人士喜欢用伪代码,初学者喜欢用流程图或N-S图,因为它们比较形象,易于理解。本书主要使用流程图和N-S图表示算法。
课后讨论
讨论上述几种算法描述工具各自的优缺点。