基于递归求解方法的递归算法设计

                        基于递归求解方法的递归算法设计

当求解问题的方法是递归(如Hanoi问题)的或者可以转换成递归方法求解时(如皇后问题),可以设计成递归算法。
例如,求f(n)=1+2+…+n(n>=1),这个问题可以转化为递归方法求解,假设“小问题”是f(n-1)=1+2+…+(n-1),是可求得,则f(n)=f(n-1)+n。
对于采用递归方法求解的问题,需要对问题本身进行分析,确定大,小问题之间的关系,构造合理的递归体。

例:采用递归算法求解迷宫问题,并输出从入口到出口的所有迷宫路径。
解:迷宫问题:求从(xi,yi)到(xe,ye)的迷宫路径,用path变量保存一条迷宫路径,其中Pathtype类型的声明如下:

typedef struct
{
    int i;              //当前方块的行号
    int j;              //当前方块的列号
} Box;
typedef struct
{
    Box data[MaxSize];
    int length;         //路径长度
} PathType;             //定义路径类型
int count=0;            //存放迷宫路径的条数

当从(xi,yi)方块找到一个相邻的可走方块(i,j)后,mgpath(i,j,xe,ye,path)表示求从(i,j)到出口(xe,ye)的迷宫路径。显然,mgpath(xi,yi,xe,ye,path)是“大问题”,而mgpath(i,j,xe,ye,path)是“小问题”(即大问题=试探一步+小问题)。求解上述迷宫问题的递归模型如下:

mgpath(xi,yi,xe,ye,path)==将(xi,yi)添加到path中;输出path中的迷宫路径;
        若(xiyi)==(xe,ye)即找到出口
mgpath(xi,yi,xe,ye,path)==是对于(xi,yi)四周的每一个相邻方块(i,j):
        若(xi,yi)不是出口可走。
        ①:将(xi,yi)添加到path中;
        ②:mg[xi][yi]=-1;
        ③:mgpath(i,j,xe,ye,path);
        ④:path回退一步并置mg[xi][yi]=0;
mgpath(xi,yi,xe,ye,path)==不做任何事情;   若(xi,yi)不是出口且不可走。

在上述模型中,当完成“小问题”mgpath(xi,yi,xe,ye,path)后将path回退并置mg[xi][yi]为0(对应④),其目的是恢复前面求迷宫路径而改变的环境,以便找出所有的迷宫路径。对应的递归算法如下:

#include <stdio.h>
#define MaxSize 100
#define M 4
#define N 4
int mg[M+2][N+2]=
{ {1, 1, 1, 1, 1, 1},
  {1, 0, 0, 0, 1, 1},
  {1, 0, 1, 0, 0, 1},
  {1, 0, 0, 0, 1, 1},
  {1, 1, 0, 0, 0, 1},
  {1, 1, 1, 1, 1, 1}
};

typedef struct
{
    int i;              //当前方块的行号
    int j;              //当前方块的列号
} Box;
typedef struct
{
    Box data[MaxSize];
    int length;         //路径长度
} PathType;             //定义路径类型
int count=0;            //存放迷宫路径的条数
int main()
{
    PathType path;
    path.length=0;              //初始化路径长度
    mgpath(1,1,M,N,path);
    return 1;
}
void mgpath(int xi,int yi,int xe,int ye,PathType path)
//求解路径为:(xi,yi)->(xe,ye)
{
    int di,k,i,j;
    if (xi==xe && yi==ye)       //找到了出口,输出路径
    {
        path.data[path.length].i = xi;
        path.data[path.length].j = yi;
        path.length++;
        printf("迷宫路径%d如下:\n",++count);
        for (k=0;k<path.length;k++)
            printf("\t(%d,%d)",path.data[k].i,path.data[k].j);
        printf("\n");
    }
    else                        //(xi,yi)不是出口
    {
        if (mg[xi][yi]==0)      //(xi,yi)是一个可走方块
        {
            di=0;
            while (di<4)        //找(xi,yi)的一个相邻方块(i,j)
            {
                switch(di)
                {
                case 0:i=xi-1; j=yi;   break;
                case 1:i=xi;   j=yi+1; break;
                case 2:i=xi+1; j=yi;   break;
                case 3:i=xi;   j=yi-1; break;
                }
                path.data[path.length].i = xi;
                path.data[path.length].j = yi;
                path.length++;
                mg[xi][yi]=-1;          //避免重复找路径
                mgpath(i,j,xe,ye,path);
                path.length--;          //回退一个方块
                mg[xi][yi]=0;           //恢复(xi,yi)为可走
                di++;
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值