递归就是方法自己调用自己,每次调用时传入不同的变量.递归有助于编程者解决复杂的问题,同时可以让代码变得整洁.

 Java编程内功-数据结构与算法「递归」(java基本数据结构和算法) Java 数据结构 算法 第1张

概念

简单地说:递归就是方法自己调用自己,每次调用时传入不同的变量.递归有助于编程者解决复杂的问题,同时可以让代码变得整洁.

递归能解决什么样的问题

  1. 各种数学问题如:八皇后问题,汉诺塔,阶乘问题,迷宫问题,球和篮子问题(google编程大赛).
  2. 各种算法中也会用到递归,比如快排,归并排序,二分查找,分治算法等.
  3. 将用栈解决的问题->递归代码比较简洁.

递归需要遵守的规则

  1. 执行一个方法时,就创建一个新的受保护的独立空间(栈空间).
  2. 方法的局部变量是独立的,不会相互影响.
  3. 如果方法中使用的变量是引用类型的变量(比如数组),就会共享该引用类型的数据.
  4. 递归必须向退出递归的条件逼近,否则就是无限递归.
  5. 当一个方法执行完毕,或者遇到return,就会返回,遵守谁调用就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕.

递归回溯解决迷宫问题

在一个二维数组中,1表示墙,求小球从指定点到终点走过的路径.

  1. packagecom.structures.recursion;
  2. publicclassMiGong{
  3. publicstaticvoidmain(String[]args){
  4. //先创建二维数组模拟迷宫,地图
  5. int[][]map=newint[8][7];
  6. //使用1表示墙,迷宫的上下左右边全部置为1
  7. for(inti=0;i<7;i++){
  8. map[0][i]=1;
  9. map[7][i]=1;
  10. }
  11. for(inti=0;i<8;i++){
  12. map[i][0]=1;
  13. map[i][6]=1;
  14. }
  15. //设置挡板
  16. map[3][1]=1;
  17. map[3][2]=1;
  18. //输出地图
  19. System.out.println("原始地图");
  20. for(inti=0;i<8;i++){
  21. for(intj=0;j<7;j++){
  22. System.out.print(map[i][j]+"");
  23. }
  24. System.out.println();
  25. }
  26. //使用递归回溯找路
  27. setWay(map,1,1);
  28. System.out.println("按策略走过的路");
  29. for(inti=0;i<8;i++){
  30. for(intj=0;j<7;j++){
  31. System.out.print(map[i][j]+"");
  32. }
  33. System.out.println();
  34. }
  35. /*
  36. 原始地图
  37. 1111111
  38. 1000001
  39. 1000001
  40. 1110001
  41. 1000001
  42. 1000001
  43. 1000001
  44. 1111111
  45. 按策略走过的路
  46. 1111111
  47. 1200001
  48. 1222001
  49. 1112001
  50. 1002001
  51. 1002001
  52. 1002221
  53. 1111111
  54. */
  55. }
  56. /**
  57. *使用递归回溯来找路,如果能map[6][5]位置,则说明通路找到
  58. *约定:当map[i][j]为0表示该点没有走过,当为1表示墙,当为2表示通路可以走,3表示该点已经走过,但是走不通
  59. *在走迷宫时,需要确定一个策略(方法),下->右->上->左,如果走不通再回溯
  60. *
  61. *@parammap表示地图
  62. *@parami从哪个位置开始行坐标
  63. *@paramj从哪个位置开始列坐标
  64. *@return如果找到通路,就返回true,否则返回false
  65. */
  66. publicstaticbooleansetWay(int[][]map,inti,intj){
  67. if(map[6][5]==2){
  68. returntrue;
  69. }else{
  70. if(map[i][j]==0){//如果当前这个点没有走过
  71. //按照策略下->右->上->左走
  72. map[i][j]=2;//假定该点可以走通
  73. if(setWay(map,i+1,j)){//向下走
  74. returntrue;
  75. }elseif(setWay(map,i,j+1)){//向右走
  76. returntrue;
  77. }elseif(setWay(map,i-1,j)){//向上走
  78. returntrue;
  79. }elseif(setWay(map,i,j-1)){//向左走
  80. returntrue;
  81. }else{
  82. map[i][j]=3;//说明该点是死路,走不通
  83. returnfalse;
  84. }
  85. }else{
  86. //如果map[i][j]!=0,说明可能是1,2,3
  87. returnfalse;
  88. }
  89. }
  90. }
  91. }

八皇后问题

在8*8的国际象棋上摆放8个皇后,使其不能相互攻击,即:任意两个皇后都不能处于同一行,同一列,同一斜线上,问有多少种摆法.

理论上应该创建一个二维数组来表示棋盘,但是实际上可以通过算法,用一个一维数组即可解决问题,arr[8]={0,4,7,5,2,6,1,3},对应arr下标表示第几行,即第几个皇后,arr[i]=val,val表示第i+1个皇后,放在第i+i行的val+1列.

  1. packagecom.structures.recursion;
  2. publicclassQueen8{
  3. //表示共有多少个皇后
  4. privateintmax=8;
  5. //定义数组array,保存皇后放置位置的结果,比如arr[8]={0,4,7,5,2,6,1,3}
  6. privateint[]array=newint[max];
  7. staticintcount=0;
  8. publicstaticvoidmain(String[]args){
  9. Queen8queen8=newQueen8();
  10. queen8.check(0);
  11. System.out.printf("总共%d摆法\n",count);//92种
  12. }
  13. //放置第n个皇后
  14. publicvoidcheck(intn){
  15. if(n==max){//n=8说明前面已经放好
  16. print();
  17. count++;
  18. return;
  19. }
  20. //依次放入皇后并判断是否冲突
  21. for(inti=0;i<max;i++){
  22. //先把当前的皇后n,放到改行的第1列
  23. array[n]=i;
  24. //判断当放置第n个皇后到第i列是,是否冲突.
  25. if(judge(n)){
  26. //接着放n+1皇后,开始递归
  27. check(n+1);
  28. }
  29. }
  30. }
  31. //查看当放置第n个皇后时,就去检测该皇后是否前面已经摆放的皇后冲突
  32. privatebooleanjudge(intn){
  33. for(inti=0;i<n;i++){
  34. //array[i]==array[n]表示第n个皇后是否与之前的皇后在同一列
  35. //Math.abs(n-i)==Math.abs(array[n]-array[i])表示第n个皇后是否与之前在同一个斜线
  36. if(array[i]==array[n]||Math.abs(n-i)==Math.abs(array[n]-array[i])){
  37. returnfalse;
  38. }
  39. }
  40. returntrue;
  41. }
  42. //将皇后摆放的位置输出
  43. publicvoidprint(){
  44. for(inti=0;i<array.length;i++){
  45. System.out.print(array[i]+"");
  46. }
  47. System.out.println();
  48. }
  49. }

【编辑推荐】

  1. 在Ubuntu Linux上安装Windows 10的最简单方法
  2. 9个Linux 常用查看系统硬件信息命令(实例详解)
  3. 一文告诉你为什么有那么多人在炒币?
  4. 推荐 10 个标星 100 K 的 GitHub 开源项目
  5. 甚至连Excel都落于下风!WPS这些功能你都知道吗

转载请说明出处
知优网 » Java编程内功-数据结构与算法「递归」(java基本数据结构和算法)

发表评论

您需要后才能发表评论