我们以马周游问题为例进行分析:
一、马周游问题描述
在一个5 * 6的棋盘中的某个位置有一只马,如果它走29步正好经过除起点外的其他位置各一次,这样一种走法则称马的周游路线,试设计一个算法,从给定的起点出发,找出它的一条周游路线。
为了便于表示一个棋盘,我们按照从上到下,从左到右对棋盘的方格编号,如下所示:
01 02 03 04 05 06
07 08 09 10 11 12
13 14 15 16 17 18
19 20 21 22 23 24
25 26 27 28 29 30
马的走法是“日”字形路线,例如当马在位置15的时候,它可以到达2、4、7、11、19、23、26和28。但是规定马是不能跳出棋盘外的,例如从位置1只能到达9和14。
二、源程序片段(C++描述)
void dfs(int x,int y,int step)
{
if (isSolved==true)
{
return;
}
if(step==30)
{
isSolved=true;
for(int i=0;i<30;i++)
{
cout<< road[i]<<" ";
}
cout<<endl;
return;
}
for(int i =0;i<8;i++)
{
if(isSolved==true)
{
return;
}
int tempx=x+inext[i][0],tempy=y+inext[i][1];
if (tempx>0&&tempx<6&&tempy>0&&tempy<7&&chess[tempx][tempy]==false)
{
road[step]=6*tempx+tempy-6;
chess[tempx][tempy]=true;
dfs(tempx,tempy,step+1);
chess[tempx][tempy]=false;
}
}
}
三、问题分析对于上面的程序片段,我们以程序片段中变量step的调用进行分析。变量step是在函数dfs()的形参列表中声明的,其作用域和生存期为函数dfs()体内。
1、对于函数dfs()的每次调用,都要重新声明一个局部变量step,并且给step赋予给定的值。
2、对于变量step,假设走到位置(4、3),step为25时,发现位置(4、3)接下来的八个方向都应经走过,那么我么就要把位置(4、3)置为false并且回退到上一步继续搜索,这个时候dfsj()返回,stepj的值为25,但是这个时候dfsi()的局部变量stepi的值其实仍然为24,这就是我们在程序中不执行step=step-1的原因。
3、假设我们将局部变量step设置为全局变量或者是静态局部变量,那么程序就要改写为下面的形式: