递归算法分析

       都说递归算法等同于循环,不过递归算法却没有循环那般的简单明了,细节处理的明晰直观。因为无法深入把握递归的细节处理,心里总是对其略有畏惧。心存畏惧可以使人见贤思齐,也可使人止步不前。故此特地花了一块时间专门的研究递归,以期消除内心的不安。

        递归最经典的例子莫过于汉诺塔,即大小不同的圆盘依次从a迁往b,期间要借助于c作为中间介质。递归算法要求逐次减小复杂度,直至最后的递归出口。递归算法相当于任务的分配,领导分配任务,他是从大处着眼,有步骤的进行。大领导分配任务给下一级领导,直到普通的员工,此时相当于递归的出口。这是一个层的概念,一个领导的任务要依赖于下一级领导任务的完成。分配任务反映到代码上就是函数调用,而函数的调用相当于一个断点,即被调用的函数处理完成之后,调用方才会向下处理。若被调用的函数没有到递归的出口,则他也会调用下一个函数完成既定的任务,直到递归的出口,这样就形成了一个函数的调用链,这是一个很多层的调动链。那么可以说整个调用链都依赖于递归的出口,不然这个调用链便永远不会结束。到达递归出口后,流程控制权返回给上一层,然后上一层进行相应的处理,直至上一层完成,然后上一层返回,然后就上上层进行处理,这是递归调用链的逆过程。直到顶层的调用,完成整个任务处理。

        举例子说明一下,汉诺塔的经典调用:

private static void move(int num, String from, String mid, String to) {
  if(num==1){
  System.out.println("move disk 1 from "+from+" to "+to);
  }
  else {
  move(num-1,from,to,mid);
  System.out.println("move disk "+num+" from " + from + " to "+to);
  move(num-1,mid,from,to);
  }

num 为盘子的个数,from为圆盘的起始位置,to为目标位置,mid为中间辅助位置,num==1为递归出口。假如num为4,即有4个盘子需要移动,则起始需要将前三个盘子移动到mid位置,然后取出第四个盘子移动到to位置,然后将mid中的3个盘子移动到to位置,这是第一层的任务的处理步骤,也是事件的整个处理流程。第一层任务完成整个任务也就完成了,不过在执行第一层的

(1)move(num-1,from,to,mid); 

的过程中,由于未到递归出口,则他需进一步的函数调用,他的处理过程为
(2)  move(num-1,from,to,mid);(3)
   System.out.println("move disk "+num+" from " + from + " to "+to);(4)
   move(num-1,mid,from,to);(5)

不过此时的任务是将上面的2个盘子移动到to位置,第三个盘子移动到mid位置,然后将to位置的2个盘子与移动到mid位置,这是第二层的递归调用。由于第二层依然没有运行到递归出口,所以他还会在运行到(1)位置时,依然新开辟一层进行整个(2)的调用,这是第三层的调用,此时运行到递归出口,则打印盘子传递信息,然后函数反馈上一层的(3)位置,然后运行(4),(5)等。运行过程跟前面大致相同,这一层结束后又反馈至上一层的(3)处,然后逐次运行,直至到第一层,然后再第一层运行(4)(5),整个过程结束。

    由此可见,递归的过程主要是开始阶段的函数层次调用,到达递归出口,然后函数又逐次返回至上一层,直至第一层,通过数据的来回完成整个递归的运行,从而完成既定的任务。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值