算法-递归算法

递归算法是把问题转化为规模缩小了的同类问题的子问题。然后递归调用函数(或过程)来表示问题的解。
本文主要从以下方面进行介绍递归算法:
1. 递归算法的概念
2. 递归算法的特点
3. 递归算法的应用
4. 递归算法的典型实例

1. 递归算法的概念

递归过程一般通过函数或子过程来实现。递归方法:在函数或子过程的内部,直接或者间接地调用自己的算法。

2. 递归算法的特点

2.1 递归的特点

(1) 递归就是在过程或函数里调用自身,分别称为直接递归和间接递归;
(2) 在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口;
(3) 递归算法解题通常显得很简洁,但递归算法解题的运行效率较低;
(4) 在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。鉴于(3)(4)特点,所以一般不提倡用递归算法设计程序。但是有些问题必须用递归解决。

2.2 递归的要求

递归算法所体现的“重复”一般有三个要求:
(1)每次调用在规模上都有所缩小(通常是减半);
(2)相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入);
(3)在问题的规模极小时必须用直接给出解答而不再进行递归调用,因而每次递归调用都是有条件的(以规模未达到直接解答的大小为条件),无条件递归调用将会成为死循环而不能正常结束。

3. 递归算法的实现

3.1 递归的设计思路

(1)确定递归公式
(2)确定边界(终了)条件

3.2 递归的设计模式

procedure aaa(k:integer);
begin
if k=1 then (边界条件及必要操作)
else begin
aaa(k-1);
(重复的操作);
end;
end;

4. 递归算法的典型实例

4.1 上楼问题/斐波那契数列

问题描述: 楼梯有n阶台阶,上楼可以一步上1阶,也可以一步上2阶,编一程序计算共有多少种不同的走法.
问题分析:设n阶台阶的走法数为f(n)
显然有
f(1) = 1;
f(2) = 2;
f(n)={f(n-1)+f(n-2)} n>2
递归结束条件: n = 1;
算法实现:

public class Step{

    public static void main(String args[]){
        System.out.println(step(3));
        System.out.println(step(4));
        System.out.println(step(15));
    }

    private static int step(int n){
        if(n == 1){  //定义出口
            return 1; 
        }else if(n == 2){ //定义出口
            return 2;
        }else{ //递归
            return step(n-1) + step(n-2); //递归公式
        }
    }
}

结果:
递归>java Step
3
5
987

4.2 汉诺塔问题

问题描述:汉诺塔问题如上图所示,将64个盘子从一个柱子移动到另一个柱子,可以借助一个柱子。每次只能移动一个盘,且不能出现小盘放在大盘上面。
这里写图片描述
问题分析:
1个盘:从原柱(src)移动到目的柱(dist);
n个盘:
(1)将(n-1)个盘子从src通过dist移动到中间柱(temp);
(2)将第n个盘子从src移动到dist;
(3)将(n-1)个盘子从temp通过src移动到dist;
算法实现

public class Hanio{
    public static StringBuffer sb = new StringBuffer();

    public static void main(String args[]){
        System.out.println(hanio(1,"src","temp","dist"));
        sb.delete(0, sb.length() - 1);
        System.out.println(hanio(2,"src","temp","dist"));
        sb.delete(0, sb.length() - 1);
        System.out.println(hanio(3,"src","temp","dist"));
        sb.delete(0, sb.length() - 1);
        System.out.println(hanio(4,"src","temp","dist"));
    }

    private static String hanio(int n, String src, String temp, String dist){
        if(n == 1){
            sb.append(move(n,src,dist)); 
        }else {
            hanio(n-1,src,dist,temp);
            //hanio(1,src,temp,dist);
            sb.append(move(n,src,dist));
            hanio(n-1,temp,src,dist);
        }
        return sb.toString();
    }
    private static String move(int n, String src, String dist){
        return "Move No." + n + " pillar from " +  src + " to " + dist + "\n"; 
    }
}

运行结果

Move No.1 pillar from src to dist

Move No.1 pillar from src to temp
Move No.2 pillar from src to dist
Move No.1 pillar from temp to dist

Move No.1 pillar from src to dist
Move No.2 pillar from src to temp
Move No.1 pillar from dist to temp
Move No.3 pillar from src to dist
Move No.1 pillar from temp to src
Move No.2 pillar from temp to dist
Move No.1 pillar from src to dist

Move No.1 pillar from src to temp
Move No.2 pillar from src to dist
Move No.1 pillar from temp to dist
Move No.3 pillar from src to temp
Move No.1 pillar from dist to src
Move No.2 pillar from dist to temp
Move No.1 pillar from src to temp
Move No.4 pillar from src to dist
Move No.1 pillar from temp to dist
Move No.2 pillar from temp to src
Move No.1 pillar from dist to src
Move No.3 pillar from temp to dist
Move No.1 pillar from src to temp
Move No.2 pillar from src to dist
Move No.1 pillar from temp to dist

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值