2021-10-21 IV. recursion

1. What is recursion Recursion is a method that calls itself, passing in different variables each time. Recursion helps ...
1.1 operation description of recursion
1.2 recursive application scenarios
1.3 rules that recursion must follow
2.1 design idea
2.2 code implementation
2.3 complete code
2.4 modify maze walking strategy
3.1 introduction to eight queens
3.2 design idea
3.3 code implementation

1. What is recursion

Recursion is a method that calls itself, passing in different variables each time.
Recursion helps programmers solve complex problems and makes code concise.

1.1 operation description of recursion


According to the running rules of the JVM:

  1. When the program executes a method, it will open up a new stack frame space in the stack space;
  2. Each space is independent of each other, that is, the data (local variables) will not be interconnected


Operation explanation:

  1. When entering the main method, a main method stack frame will be opened in the stack, and then the statements will be executed in turn,
  2. When you execute the test(4) method, you will enter the test method body to open up a new stack frame... And so on
  3. After the method runs, the memory space in the stack will be recycled automatically. As can be seen from the figure, the stack frame with n=2 is recycled first, then n=3... And finally return to the main method
  4. Therefore, the output order of the program is n=2,n=3,n=4

1.2 recursive application scenarios

  1. Various mathematical problems, such as: 8 queen problem, Hanoi Tower, factorial problem, maze problem, ball and basket problem (google programming competition)
  2. Recursion is also used in various algorithms, such as fast sorting, merge sorting, binary search, divide and conquer algorithm, etc
  3. Problems to be solved with stack – > recursive code is relatively concise

1.3 rules that recursion must follow

1. Each time a method is executed, a new protected independent space (stack space) is created - the default is (main)
2. The local variables of the method are independent and will not affect each other, such as n variables
3. If a reference type variable (such as an array) is used in the method, the data of the reference type will be shared. (because reference type variables are stored in the heap, which is a shared memory space)
4. Recursion must approach the condition of exiting recursion, otherwise it is infinite recursion (StackOverflowError and stack overflow)
5. When a method completes execution or encounters a return, it will return. The result will be returned to whoever calls it. At the same time, when the method completes execution or returns, the method will also complete execution.

2. Recursive backtracking algorithm (maze problem)

According to the actual application scenario of recursion, the maze problem is selected to describe the recursive backtracking algorithm

2.1 design idea

  1. Use a two-dimensional array to simulate the maze, and manually add a baffle (the fence is represented by 1, the walkable space is represented by 0, the walkable route is represented by 2, and the passable route is represented by 3)
  2. Specify the start point and end point, and judge whether to jump out of recursion when reaching the end point
  3. Set walking rules: lower = > right = > upper = > left

2.2 code implementation

Generate maze

private static int[][] createMiGong() { int[][] miGong = new int[8][7]; for (int i = 0; i < miGong.length; i++) { for (int j = 0; j < miGong[i].length; j++) { miGong[0][j] = miGong[miGong.length - 1][j] = miGong[i][0] = miGong[i][miGong[i].length - 1] = miGong[3][1] = miGong[3][2] = 1; System.out.print(miGong[i][j] + "\t"); } System.out.println(); } return miGong; }
1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1

Labyrinth

/** * Labyrinth */ public static boolean miGongHuiSu(int[][] mig, int i, int j) { //When it reaches the exit, it directly returns true. As long as the return value is true, it starts backtracking if (mig[6][5] == 2) { return true; } else { //Not yet if (mig[i][j] == 0) { //Suppose it works mig[i][j] = 2; //Go down and return true if you reach the end if (miGongHuiSu(mig, i + 1, j)) { return true; } else if (miGongHuiSu(mig, i, j + 1)) { //Go right return true; } else if (miGongHuiSu(mig, i - 1, j)) { //Go up return true; } else if (miGongHuiSu(mig, i, j - 1)) { //Go left return true; } else { //I can't go up, down, left and right mig[i][j] = 3; return false; } } else { //When mig[i][j]= When 0, it returns false, indicating that the current position is either a wall, has passed, or can't go return false; } } }

2.3 complete code

public class Demo14 { public static void main(String[] args) { //8 rows and 7 columns labyrinth plus baffle, and 1 is baffle int[][] miGong = createMiGong(); System.out.println("Start the maze~~"); miGongHuiSu(miGong, 1, 1); show(miGong); } /** * Generate maze * @return */ private static int[][] createMiGong() { int[][] miGong = new int[8][7]; for (int i = 0; i < miGong.length; i++) { for (int j = 0; j < miGong[i].length; j++) { miGong[0][j] = miGong[miGong.length - 1][j] = miGong[i][0] = miGong[i][miGong[i].length - 1] = miGong[3][1] = miGong[3][2] = 1; System.out.print(miGong[i][j] + "\t"); } System.out.println(); } return miGong; } /** * Show maze */ public static void show(int[][] mig) { for (int[] ints : mig) { for (int anInt : ints) { System.out.print(anInt + "\t"); } System.out.println(); } } /** * Labyrinth */ public static boolean miGongHuiSu(int[][] mig, int i, int j) { //When it reaches the exit, it directly returns true. As long as the return value is true, it starts backtracking if (mig[6][5] == 2) { return true; } else { //Not yet if (mig[i][j] == 0) { //Suppose it works mig[i][j] = 2; //Go down if (miGongHuiSu(mig, i + 1, j)) { // If it can reach the end point, it will return true. Otherwise, it will return false to the following else if return true; } else if (miGongHuiSu(mig, i, j + 1)) { //Go right return true; } else if (miGongHuiSu(mig, i - 1, j)) { //Go up return true; } else if (miGongHuiSu(mig, i, j - 1)) { //Go left return true; } else { //I can't go up, down, left and right mig[i][j] = 3; return false; } } else { //When mig[i][j]= When 0, it returns false, indicating that the current position is either a wall, has passed, or can't go return false; } } } }

If you don't understand the output results, it is recommended to debug more

1 1 1 1 1 1 1 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 1 1 1 1 Start the maze~~ 1 1 1 1 1 1 1 1 2 0 0 0 0 1 1 2 2 2 0 0 1 1 1 1 2 0 0 1 1 0 0 2 0 0 1 1 0 0 2 0 0 1 1 0 0 2 2 2 1 1 1 1 1 1 1 1

2.4 modify maze walking strategy

Up = > right = > down = > left
This code can be used by pasting it into the complete code and adding related calls

/** * Modify maze walking strategy: up - "" right - "" down - "" left * And with step size calculation, it can be used to compare the shortest path, */ public static boolean miGongHuiSu2(int[][] mig, int i, int j, int step) { //Reach the exit if (mig[6][5] == 2) { System.out.println(step); return true; } else { //Not yet if (mig[i][j] == 0) { step++; //Suppose it works mig[i][j] = 2; //Go up if (miGongHuiSu2(mig, i - 1, j, step)) { return true; } else if (miGongHuiSu2(mig, i, j + 1, step)) { //Go right return true; } else if (miGongHuiSu2(mig, i + 1, j, step)) { //Go down return true; } else if (miGongHuiSu2(mig, i, j - 1, step)) { //Go left return true; } else { step--; //I can't go up, down, left and right mig[i][j] = 3; return false; } } else { step--; //mig[i][j]!=0,eg:1,2,3 return false; } } }

Output results

Go through the maze after modifying the strategy~~ 10 // step 1 1 1 1 1 1 1 1 2 2 2 2 2 1 1 0 0 0 0 2 1 1 1 1 0 0 2 1 1 0 0 0 0 2 1 1 0 0 0 0 2 1 1 0 0 0 0 2 1 1 1 1 1 1 1 1
3. Question of Queen VIII

3.1 introduction to eight queens

1. The eight queens problem is an ancient and famous problem and a typical case of backtracking algorithm. The problem was put forward by international chess player Max Bethel in 1848: in August × Eight queens are placed on the 8-grid chess so that they can't attack each other,
2. Human words: any two Queens can't be in the same row, column or slash. How many kinds of pendulum methods are there.

3.2 design idea

Operation steps:

  1. The first queen puts the first row and the first column first
  2. The second queen is placed in the first column of the second row, and then judge whether it is OK. If it is not OK, continue to put it in the second column and the third column... Until a suitable position is found
  3. Continue the third queen, or the first and second columns... Until the eighth queen can also be placed in a non conflicting position (it may fall back to the queen placed before the adjustment in step 2 in this process), and a correct solution is found when you start looking for the ninth queen
  4. When a correct solution is obtained, start backtracking. The stack will backtrack to the previous stack, move the position of the queen in the previous stack, and even backtrack multiple stacks. Adjust the position of multiple queens, that is, recursively backtrack according to the idea of steps 2-3.
  5. Repeat steps 1-4 to get all the solutions

Note: theoretically, a two-dimensional array should be created to represent the chessboard, but in fact, the problem can be solved by using a one-dimensional array through the algorithm. Arr [8] =
arr[i]: indicates the i+1 line, i.e. the i+1 queen;
arr[i] = val: indicates the i+1 Queen, which is placed in column val+1 of row i+1

3.3 code implementation

public class Demo15 { private final static Integer MAX = 8; /** * Here, a one-dimensional array is used to store the solution */ private final static Integer[] ARRAY = new Integer[MAX]; /** * Record the number of solutions */ private static Integer count = 0; /** * Record judgment times */ private static Integer bif = 0; public static void main(String[] args) { check(0); System.out.printf("Altogether %d A solution\n", count); System.out.printf("A total of judgment%d second", bif); } /** * Judge whether the queen conflicts * 3.There is no need to judge whether the same row is used, because in the design, the row is represented by the array corner mark, and N is incremented every time (the result will not appear in the same row) * * @param n The queen, or the queen of the line. */ private static boolean judge(int n) { bif++; for (int i = 0; i < n; i++) { /* * 1,ARRAY[i].equals(ARRAY[n]) Indicates whether the nth queen is in the same column as the previous n-1 queens * 2,Math.abs(n-i) == Math.abs(ARRAY[n] - ARRAY[i]) * Indicates whether the nth queen and the ith queen are on the same slash (i.e. find the slope), * Since Math.abs() is an absolute value, only the case of (y2-y1)/(x2-x1) = 1 needs to be considered */ if (ARRAY[i].equals(ARRAY[n]) || Math.abs(n - i) == Math.abs(ARRAY[n] - ARRAY[i])) { return false; } } return true; } /** * Place the n th queen */ private static void check(int n) { // It indicates that the ninth queen is judged, indicating that there is no conflict among the eight queens, and the results can be printed directly if (n == MAX) { print(); return; } /* * Each time the check function is called, it is placed from the first column, and ARRAY[n] represents row n+1 */ for (int i = 0; i < MAX; i++) { ARRAY[n] = i; // This shows that there is no conflict. You can call the function recursively to determine the position of the next queen if (judge(n)) { check(n + 1); } // If there is a conflict, i + + will enter the next loop of for, and backtracking is implemented here } } /** * Output Queen's placement results */ private static void print() { count++; for (Integer integer : ARRAY) { System.out.print(integer + " "); } System.out.println(); } }
LastGeneral catalogueNext3, StackData structure (Java) directoryUnfinished to be continued

25 October 2021, 08:57 | Views: 9364

Add new comment

For adding a comment, please log in
or create account

0 comments