算法演义(05)

IT商界

  算法心诀

  在第一期的算法演义中,我们讲过了排序算法中的冒泡算法。对于初学者而言,看懂原理比较简单的冒泡算法应该不是难事,但如果要处理一个陌生的 问题时(也就是要自己设计算法时)往往又不知该如何下手。根据我自己学习算法的体会而言,刚开始学习算法的难点不在于能看懂多少种算法原理,关键是要熟悉用计算机处理 问题的常用手段和如何将我们的思维映射到计算机的工作流上。所以从本期开始我们将探讨算法的设计思路──也就是算法心诀。

  “懒人”的选择──递归

  说到递归,很多初学者都很害怕。因为,递归看起来似乎不太符合我们日常的思维习惯。其实递归是一种很重要的程序设计方法和技术,使用递归可以简化程序设计的过程,所以我认为递归是适合像我这样的“懒人”的开发方式。递归算法本质上是将较复杂的问题分解成较简单的问题,并直到最简单。它的最大特点就是自己调用自己。我们举个简单点的例子,如果要吃到一块包了很多层糖纸的糖,我们就要从外到里一层一层地剥掉糖纸直到看见糖为止。那么用程序来完成这个剥N(N>0)层糖纸的工作,应该怎么办呢?

  有朋友可能会想到,做个循环,重复做N次剥糖纸的动作不就行了!(PASCAL的程序实现如下)

  //以下是用有限循环来剥N层糖纸程序的示例

  procedureBoTangZhi(N:integer);//N为指定的糖纸层数

  var

   I:integer;

  begin

  forI:=1toNdo

  begin

   //完成剥一层糖纸的工作

  end;

  end;

  //示例结束

  现在我要问一个问题,如果N是未知的怎么办?而且我们还要得到究竟我们剥了几层糖纸怎么办。聪明的朋友会说简单,我们做一个死循环来剥糖纸,再在死循环中加一条判断语句,来判断是否已经看到糖,如果看到糖,记下当前剥糖纸的层数并跳出死循环。这个方法是可以的,由于篇幅原因这里不给出程序示例。这里,我介绍一下用递归怎么处理。PASCAL的程序实现如下。

  //以下是用递归来剥N层糖纸程序的示例

  functionBoTangZhi(n:integer):integer//没有给定的糖纸层数,初次调用时令n=1,返回值就是糖纸的层数

  begin

   //完成剥一层糖纸的工作

  ifISTangthen//ISTang判断是否是糖的自函数,如果是糖就返回当前的糖纸层数

   begin

  result:=n

   end

   else

   begin

  result:=BoTangZhi(n+1); //!!!自己调用自己,只是当前的层数有所变化。

   end;

  end;

  从上面的示例我们基本可以看出,递归的过程一般有如下的形式:

  procedure/functionP(参数表)/:返回值

  begin

   if...then判断是否在出口

   begin

  简单操作或返回值

   end

   else

   begin

  简单操作;

  P(参数表);/result:=P(参数表)

  简单操作;

  end;

  end;

  上面只是简单介绍了递归算法,为了更好理解递归,唯一的办法就是多尝试!这里我给大家出一个算法题,我会在接下来的编程沙龙里讲解这个题目。

  精彩题目:由8×8见方的棋盘上要放置8个棋子,要求任意两个棋子不能出现在同一行、同一列或同一对角线上。请你给出这8个棋子的摆放方式。

  这道题读者朋友可以用你最擅长的语言和编程工具来完成,答题方式为:把你的答案发送到software@cpcw.com,邮件主题写上“算法演义答题”。我们会从中选取答题最好的参赛者,并发送精美奖品。