递归(recursion)是指在定义自身的同时又出现了对自身的引用。如果一个算法直接或间接地调用自己,则称这个算法是一个递归算法。
任何一个有意义的递归算法总是由两部分组成:递归调用与递归终止条件。
/** * 阶汉诺塔问题可以描述为:假设有X、Y、Z 三个塔座,初始时有n 个大小不一的 * 盘子按照从小到大的次序放在塔座X 上。现在要求将塔座X 上的所有盘子移动到塔座Z 上 * 并保持原来的顺序,在移动过程中要满足以下要求:在塔座之间一次只能移动一个盘子并且 * 任何时候大盘子都不能放到小盘子上。 */ public static void hanio (int n, char x, char y, char z) { if (n == 1) move( x, n, z); else { hanio (n - 1, x, z, y); move(x, n, z); hanio(n - 1, y, x, z); } } private static void move(char x, int n, char y) { System.out.println ("Move " + n + " from " + x + " to " + y); }
堆栈实现:
/** * 求解从迷宫中的起点到某个终点的路径 */ public class Maze { public static void mazeExit(char[][] maze, int sx, int sy, int ex, int ey) { Cell[][] cells = createMaze(maze); //创建化迷宫 printMaze(cells); //打印迷宫 Stack s = new StackArray(); //构造堆栈 Cell startCell = cells[sx][sy]; //起点 Cell endCell = cells[ex][ey]; //终点 s.push(startCell); //起点入栈 startCell.visited = true; //标记起点已被访问 while (!s.isEmpty()) { Cell current = (Cell)s.peek(); if (current == endCell){ //路径找到 System.out.println("共有" + s.getSize() + "步"); while(!s.isEmpty()){ Cell cell = (Cell)s.pop();//沿路返回将路径上的单元设为* cell.c = '*'; //堆栈中与cell 相邻的单元才是路径的组成部分,除此之外, //堆栈中还有记录下来但是未继续向下探索的单元, //这些单元直接出栈 while(!s.isEmpty() && !isAdjoinCell((Cell)s.peek(), cell)) s.pop(); } System.out.println("找到从起点到终点的路径。"); printMaze(cells); return; } else { //如果当前位置不是终点 int x = current.x; int y = current.y; int count = 0; if(isValidWayCell(cells[x + 1][y])){ //向下 s.push(cells[x + 1][y]); cells[x+1][y].visited = true; count++;} if(isValidWayCell(cells[x][y + 1])){ //向右 s.push(cells[x][y + 1]); cells[x][y + 1].visited = true; count++;} if(isValidWayCell(cells[x - 1][y])){ //向上 s.push(cells[x - 1][y]); cells[x - 1][y].visited = true; count++;} if(isValidWayCell(cells[x][y - 1])){ //向左 s.push(cells[x][y - 1]); cells[x][y - 1].visited = true; count++;} if (count == 0) s.pop();//如果是死点,出栈 }//end of if }//end of while System.out.println("没有从起点到终点的路径。"); } private static void printMaze(Cell[][] cells) { for (int x = 0; x < cells.length; x++){ for (int y = 0; y < cells[x].length; y++) System.out.print(cells[x][y].c + " "); System.out.println(); } } private static boolean isAdjoinCell(Cell cell1, Cell cell2) { if (cell1.x == cell2.x && Math.abs(cell1.y - cell2.y) < 2) return true; if (cell1.y == cell2.y && Math.abs(cell1.x - cell2.x) < 2) return true; return false; } private static boolean isValidWayCell(Cell cell) { return cell.c == '0' && !cell.visited; } private static Cell[][] createMaze(char[][] maze) { Cell[][] cells = new Cell[maze.length][]; for (int x = 0; x < maze.length; x++) { char[] row = maze[x]; cells[x] = new Cell[row.length]; for (int y = 0; y < row.length; y++) cells[x][y] = new Cell(x, y, maze[x][y], false); } return cells; } public static void main(String[] args) { char[][] maze = { {'1', '1', '1', '1', '1', '1', '1', '1', '1', '1'}, {'1', '0', '0', '1', '1', '1', '0', '0', '1', '1'}, {'1', '0', '0', '1', '1', '0', '0', '1', '0', '1'}, {'1', '0', '0', '0', '0', '0', '0', '1', '0', '1'}, {'1', '0', '0', '0', '0', '1', '1', '0', '0', '1'}, {'1', '0', '0', '1', '1', '1', '0', '0', '0', '1'}, {'1', '0', '0', '0', '0', '1', '0', '1', '0', '1'}, {'1', '0', '1', '1', '0', '0', '0', '0', '0', '1'}, {'1', '1', '0', '0', '0', '0', '1', '0', '0', '1'}, {'1', '1', '1', '1', '1', '1', '1', '1', '1', '1'}, }; mazeExit(maze, 1, 1, 2, 8); } } class Cell { int x = 0; //单元所在行 int y = 0; //单元所在列 boolean visited = false; //是否访问过 char c = ' '; //是墙('1')、可通路('0')或起点到终点的路径('*') public Cell(int x, int y, char c, boolean visited) { this.x = x; this.y = y; this.c = c; this.visited = visited; } }