数据结构与算法----递归

简介: 数据结构与算法----递归

1、迷宫回溯问题

package com.yhb.code.datastructer.recursion¥5;
public class MiGong {
  public static void main(String[] args) {
    // 先创建一个二维数组,模拟迷宫
    // 地图
    int[][] map = new int[8][7];
    // 使用1 表示墙
    // 上下全部置为1
    for (int i = 0; i < 7; i++) {
      map[0][i] = 1;
      map[7][i] = 1;
    }
    // 左右全部置为1
    for (int i = 0; i < 8; i++) {
      map[i][0] = 1;
      map[i][6] = 1;
    }
    //设置挡板, 1 表示
    map[3][1] = 1;
    map[3][2] = 1;
//    map[1][2] = 1;
//    map[2][2] = 1;
    // 输出地图
    System.out.println("地图的情况");
    for (int i = 0; i < 8; i++) {
      for (int j = 0; j < 7; j++) {
        System.out.print(map[i][j] + " ");
      }
      System.out.println();
    }
    //使用递归回溯给小球找路
    setWay(map, 1, 1);
//    setWay2(map, 1, 1);
    //输出新的地图, 小球走过,并标识过的递归
    System.out.println("小球走过,并标识过的 地图的情况");
    for (int i = 0; i < 8; i++) {
      for (int j = 0; j < 7; j++) {
        System.out.print(map[i][j] + " ");
      }
      System.out.println();
    }
  }
  //使用递归回溯来给小球找路
  //说明
  //1. map 表示地图
  //2. i,j 表示从地图的哪个位置开始出发 (1,1)
  //3. 如果小球能到 map[6][5] 位置,则说明通路找到.
  //4. 约定: 当map[i][j] 为 0 表示该点没有走过 当为 1 表示墙  ; 2 表示通路可以走 ; 3 表示该点已经走过,但是走不通
  //5. 在走迷宫时,需要确定一个策略(方法) 下->右->上->左 , 如果该点走不通,再回溯
  /**
   *
   * @param map 表示地图
   * @param i 从哪个位置开始找
   * @param j
   * @return 如果找到通路,就返回true, 否则返回false
   */
  public static boolean setWay(int[][] map, int i, int j) {
    if(map[6][5] == 2) { // 通路已经找到ok
      return true;
    } else {
      if(map[i][j] == 0) { //如果当前这个点还没有走过
        //按照策略 下->右->上->左  走
        map[i][j] = 2; // 假定该点是可以走通.
        if(setWay(map, i+1, j)) {//向下走
          return true;
        } else if (setWay(map, i, j+1)) { //向右走
          return true;
        } else if (setWay(map, i-1, j)) { //向上
          return true;
        } else if (setWay(map, i, j-1)){ // 向左走
          return true;
        } else {
          //说明该点是走不通,是死路
          map[i][j] = 3;
          return false;
        }
      } else { // 如果map[i][j] != 0 , 可能是 1, 2, 3
        return false;
      }
    }
  }
  //修改找路的策略,改成 上->右->下->左
  public static boolean setWay2(int[][] map, int i, int j) {
    if(map[6][5] == 2) { // 通路已经找到ok
      return true;
    } else {
      if(map[i][j] == 0) { //如果当前这个点还没有走过
        //按照策略 上->右->下->左
        map[i][j] = 2; // 假定该点是可以走通.
        if(setWay2(map, i-1, j)) {//向上走
          return true;
        } else if (setWay2(map, i, j+1)) { //向右走
          return true;
        } else if (setWay2(map, i+1, j)) { //向下
          return true;
        } else if (setWay2(map, i, j-1)){ // 向左走
          return true;
        } else {
          //说明该点是走不通,是死路
          map[i][j] = 3;
          return false;
        }
      } else { // 如果map[i][j] != 0 , 可能是 1, 2, 3
        return false;
      }
    }
  }
}

2、八皇后问题

package com.yhb.code.datastructer.recursion¥5;
public class  Queue8 {
  //定义一个max表示共有多少个皇后
  int max = 8;
  //定义数组array, 保存皇后放置位置的结果,比如 arr = {0 , 4, 7, 5, 2, 6, 1, 3}
  int[] array = new int[max];
  static int count = 0;
  static int judgeCount = 0;
  public static void main(String[] args) {
    //测试一把 , 8皇后是否正确
    Queue8 queue8 = new Queue8();
    queue8.check(0);
    System.out.printf("一共有%d解法", count);
    System.out.printf("一共判断冲突的次数%d次", judgeCount); // 1.5w
  }
  //编写一个方法,放置第n个皇后
  //特别注意: check 是 每一次递归时,进入到check中都有  for(int i = 0; i < max; i++),因此会有回溯
  private void check(int n) {
    if(n == max) {  //n = 8 , 其实8个皇后就既然放好
      print();
      return;
    }
    //依次放入皇后,并判断是否冲突
    for(int i = 0; i < max; i++) {
      //先把当前这个皇后 n , 放到该行的第1列
      array[n] = i;
      //判断当放置第n个皇后到i列时,是否冲突
      if(judge(n)) { // 不冲突
        //接着放n+1个皇后,即开始递归
        check(n+1); //
      }
      //如果冲突,就继续执行 array[n] = i; 即将第n个皇后,放置在本行得 后移的一个位置
    }
  }
  //查看当我们放置第n个皇后, 就去检测该皇后是否和前面已经摆放的皇后冲突
  /**
   *
   * @param n 表示第n个皇后
   * @return
   */
  private boolean judge(int n) {
    judgeCount++;
    for(int i = 0; i < n; i++) {
      // 说明
      //1. array[i] == array[n]  表示判断 第n个皇后是否和前面的n-1个皇后在同一列
      //2. Math.abs(n-i) == Math.abs(array[n] - array[i]) 表示判断第n个皇后是否和第i皇后是否在同一斜线
      // n = 1  放置第 2列 1 n = 1 array[1] = 1
      // Math.abs(1-0) == 1  Math.abs(array[n] - array[i]) = Math.abs(1-0) = 1
      //3. 判断是否在同一行, 没有必要,n 每次都在递增
      if(array[i] == array[n] || Math.abs(n-i) == Math.abs(array[n] - array[i]) ) {
        return false;
      }
    }
    return true;
  }
  //写一个方法,可以将皇后摆放的位置输出
  private void print() {
    count++;
    for (int i = 0; i < array.length; i++) {
      System.out.print(array[i] + " ");
    }
    System.out.println();
  }
}


相关文章
|
2月前
|
算法 Python
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果
在Python编程中,分治法、贪心算法和动态规划是三种重要的算法。分治法通过将大问题分解为小问题,递归解决后合并结果;贪心算法在每一步选择局部最优解,追求全局最优;动态规划通过保存子问题的解,避免重复计算,确保全局最优。这三种算法各具特色,适用于不同类型的问题,合理选择能显著提升编程效率。
64 2
|
3月前
|
算法 搜索推荐 Shell
数据结构与算法学习十二:希尔排序、快速排序(递归、好理解)、归并排序(递归、难理解)
这篇文章介绍了希尔排序、快速排序和归并排序三种排序算法的基本概念、实现思路、代码实现及其测试结果。
46 1
|
7月前
|
存储 算法 程序员
数据结构与算法===递归
数据结构与算法===递归
|
3月前
|
存储
【数据结构】二叉树链式结构——感受递归的暴力美学
【数据结构】二叉树链式结构——感受递归的暴力美学
|
3月前
【初阶数据结构】打破递归束缚:掌握非递归版快速排序与归并排序
【初阶数据结构】打破递归束缚:掌握非递归版快速排序与归并排序
|
3月前
|
算法 定位技术
数据结构与算法学习九:学习递归。递归的经典实例:打印问题、阶乘问题、递归-迷宫问题、八皇后问题
本文详细介绍了递归的概念、重要规则、形式,并展示了递归在解决打印问题、阶乘问题、迷宫问题和八皇后问题等经典实例中的应用。
58 0
|
5月前
|
算法
【算法】递归、搜索与回溯——汉诺塔
【算法】递归、搜索与回溯——汉诺塔
|
5月前
【数据结构】遍历二叉树(递归思想)-->赋源码
【数据结构】遍历二叉树(递归思想)-->赋源码
57 4
|
6月前
|
算法 Python
python中算法递归错误(Recursion Errors)
【7月更文挑战第18天】
97 1
|
5月前
|
算法
【算法】递归总结:循环与递归的区别?递归与深搜的关系?
【算法】递归总结:循环与递归的区别?递归与深搜的关系?
118 0