1.1 递归基础介绍

基本概念

递归是一种程序设计技术,允许一个方法调用自己以达到最终目的。

递归与迭代

  1. 迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。即迭代过程的每一次结果,都是由对前一次所得结果施行相同的运算步骤得到的。
  2. 理论上递归和迭代可以相互转换。迭代一定可以转化为递归,递归不一定能转化为迭代。
  3. 实际应用中递归的算法要比迭代效率低,因为程序每调用一个函数,都要为其分配栈空间。但理论上,对于同一问题,递归和迭代的算法时间复杂度是相同的。
  4. 对于某些问题,递归是最精炼和适当的算法,但对于其他的问题,递归则不如迭代解法直观。
  5. 示例:计算1-N的和
    递归实现
public int sum(int num) {
	int result;
	if(num == 1) {
		result = 1;
	}else {
		result = num + sum(num-1);
	}
	return result;
}

迭代实现

public int sum(int num){
	int result = 0;
	for(int i=1; i<=num; i++){
		result += i;
	}
}

递归需要遵循的规则

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

递归解决迷宫问题

/**
 * 代码来自 《Java程序设计教程(第七版)》,修改变量名是我最后的倔强
 *
 */
public class MazeQuestion {
	public static void main(String[] args) {
		Maze m = new Maze();
		System.out.println(m);
		if(m.traverse(0, 0)) {
			System.out.println("已找到迷宫路径。");
		}else {
			System.out.println("迷宫没有路径。");
		}
		System.out.println(m);
	}
}
/**
 * 迷宫类
 * @author dxt
 *
 */
class Maze{
	//迷宫,入口为grid[0][0],出口为右下角元素,数字为1表示迷宫中的路,0表示墙
	private int[][] grid = {{1,1,1,0,1,1,0,0,0,1,1,1,1},
							{1,0,1,1,1,0,1,1,1,1,0,0,1},
							{0,0,0,0,1,0,1,0,1,0,1,0,0},
							{1,1,1,0,1,1,1,0,1,0,1,1,1},
							{1,0,1,0,0,0,0,1,1,1,0,0,1},
							{1,0,1,1,1,1,1,1,0,1,1,1,1},
							{1,0,0,0,0,0,0,0,0,0,0,0,0},
							{1,1,1,1,1,1,1,1,1,1,1,1,1}};
	private final int PATH = 3;	//走出迷宫的路径用数字3表示
	private final int TRIED = 4;	//走过的但不通的路用数字4表示
	/**
	 * 使用递归去遍历整个迷宫,在遍历过程中将 路径 标示出来
	 * @param row
	 * @param col
	 * @return
	 */
	public boolean traverse(int row, int col) {
		boolean done = false;
		//先判断输入的 row 和 col 是否合法
		if(valid(row, col)) {	//如果合法
			grid[row][col] = TRIED;	//遍历此合法位置
			if(row == grid.length-1 && col == grid[0].length-1) {
				//遍历完毕(到了迷宫出口)
				done = true;
			}else {
				done = traverse(row+1, col);	//下移
				if(!done) {
					done = traverse(row, col+1);	//右移
				}
				if(!done) {
					done = traverse(row-1, col);	//上移
				}
				if(!done) {
					done = traverse(row, col-1);	//左移
				}
			}
			if(done) {
				grid[row][col] = PATH;
			}
		}
		return done;
	}
	//判断索引是否合法
	public boolean valid(int row, int col) {
		if(row >= 0 && row < grid.length && col >= 0 && col < grid[0].length) {
			if(grid[row][col] == 1) {
				return true;
			}
		}
		return false;
	}
	//输出grid
	public String toString() {
		String result = "\n";
		for(int i=0; i<grid.length; i++) {
			for(int j=0; j<grid[0].length; j++) {
				result += grid[i][j] + " ";
			}
			result += "\n";
		}
		return result;
	}
}

结果
p

©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页