递归是指方法在执行的过程中自己调用自己。
用递归能解决的问题通常能将问题不断缩小为性质相同但规模更小的问题(递归情况),直到问题足够小能够直接解决(基本情况)。
递归程序编写有4个要点:
1问题是否可以递归描述?
2递归结束的条件是什么?
3递归调用之前做什么准备工作?
4递归调用之后做什么收尾工作?
以下通过一个稍微复杂的程序来举例说明一下如何编写递归程序。
有一只中国象棋中的 “ 马 ” ,在半张棋盘的左下角出发,向右上角跳去。规定只许向右跳(可上,可下,但不允许向左跳)。请编程求从左下角跳到右上角共有多少种不同跳法。
按照“马走日”的规则这匹马有4种方向可以选择:
方向一:X+1,y+2
方向二:X+2,y+1
方向三:X+1,y-2
方向四:X+2,y-1
1 问题是否可以递归陈述?
一匹马从(sx,sy)点跳到(tx,ty)点的路线个数=
从(sx+1,sy+2)点跳到(tx,ty)点的路线个数+
从(sx+2,sy+1)点跳到(tx,ty)点的路线个数+
从(sx+1,sy-2)点跳到(tx,ty)点的路线个数+
从(sx+2,sy-1)点跳到(tx,ty)点的路线个数
这样我们把一个距离终点比较远的跳马问题拆分成了离终点比较近的四个小的跳马问题。
2 递归结束的准则是什么?
当跳到终点时,递归结束;
当跳到棋盘以外时,递归结束;
3 在递归调用之前要做什么?
保存当前的路径;
4 在递归调用之后要做什么?
恢复到上一步的位置;
根据上述的思路,编写的java程序如下:
publicclassjumpHorse {
Stringroad;
intnumberOfRoad;
publicjumpHorse() {
road="";
numberOfRoad=0;
}
publicstaticvoidmain(String[] args){
jumpHorseplay=newjumpHorse();
play.jump(9,5,0,0);
System.out.println("The number of roads is "+ play.numberOfRoad);
}
publicbooleanjump(intm, intn, intsx, intsy){
StringtempRoad="";
tempRoad=road;
if (sx==m-1 &&sy==n-1){//到终点了
road = road +"("+sx+","+sy+")";
System.out.println("for "+m+"*"+n+" chessboard one road is"+road);
numberOfRoad++;
road=tempRoad;
returntrue;
}else
{
if (sx>m-1 || sy>n-1 || sy<0) //跳出边界了,此条路径失败
returnfalse;
else
{//未跳出边界,也未到达目的地
road = road +"("+sx+","+sy+")";
if (jump(m,n,sx+1,sy+2) | jump(m,n,sx+2,sy+1) | jump(m,n,sx+1,sy-2) | jump(m,n,sx+2,sy-1))
{
road=tempRoad;
returntrue;
}
else
{
road=tempRoad;
returnfalse;
}
}
}
}
}
该程序的执行结果如下:
for 9*5 chessboard one roadis(0,0)(1,2)(2,4)(3,2)(4,4)(5,2)(6,4)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,4)(3,2)(4,4)(5,2)(6,0)(7,2)(8,4)
for 9*5 chessboard one road is(0,0)(1,2)(2,4)(3,2)(4,4)(6,3)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,4)(3,2)(5,3)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,4)(3,2)(4,0)(5,2)(6,4)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,4)(3,2)(4,0)(5,2)(6,0)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,4)(3,2)(5,1)(6,3)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,4)(3,2)(5,1)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,4)(4,3)(6,4)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,4)(4,3)(5,1)(6,3)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,4)(4,3)(5,1)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(3,3)(4,1)(5,3)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(3,3)(4,1)(6,0)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(3,3)(5,2)(6,4)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(3,3)(5,2)(6,0)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,0)(3,2)(4,4)(5,2)(6,4)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,0)(3,2)(4,4)(5,2)(6,0)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,0)(3,2)(4,4)(6,3)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,0)(3,2)(5,3)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,0)(3,2)(4,0)(5,2)(6,4)(7,2)(8,4)
for 9*5 chessboard one road is(0,0)(1,2)(2,0)(3,2)(4,0)(5,2)(6,0)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,0)(3,2)(5,1)(6,3)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,0)(3,2)(5,1)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,0)(4,1)(5,3)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(2,0)(4,1)(6,0)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(3,1)(4,3)(6,4)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(3,1)(4,3)(5,1)(6,3)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(3,1)(4,3)(5,1)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(3,1)(5,2)(6,4)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(1,2)(3,1)(5,2)(6,0)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(2,1)(3,3)(4,1)(5,3)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(2,1)(3,3)(4,1)(6,0)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(2,1)(3,3)(5,2)(6,4)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(2,1)(3,3)(5,2)(6,0)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(2,1)(4,2)(6,3)(8,4)
for 9*5 chessboard one roadis(0,0)(2,1)(4,0)(5,2)(6,4)(7,2)(8,4)
for 9*5 chessboard one roadis(0,0)(2,1)(4,0)(5,2)(6,0)(7,2)(8,4)
The number of roads is 37