目录
一.递归基本介绍
简单的说:递归就是自己调用自己,每次调用时传入不同的变量,递归有助于解决复杂问题,同时让代码变得简洁。
二.简单的递归举例
1.斐波那契数列
public class Recursion {
public static void main(String[] args) {
T t1 = new T();
int h = t1.test(1);
System.out.println(h);
}
}
//斐波那契
class T{
public int test(int n){
if (n >= 1){
if (n ==1 || n == 2){
return 1;
}else {
return test(n - 1) + test(n - 2);//递归调用
}
}else return -1;
}
}
2.猴子吃桃
问题描述:猴子第一天吃了若干个桃子,当即吃了一半,还不解馋,又多吃了一个; 第二天,吃剩下的桃子的一半,还不过瘾,又多吃了一个;以后每天都吃前一天剩下的一半多一个,到第10天想再吃时,只剩下一个桃子了。问第一天共吃了多少个桃子?
思路:10day————s10=1
9day—————s9=4
8day—————s8=10
......
1day—————s1=1534
规律:sn = (s(n + 1)+ 1)* 2
public class Recursion {
public static void main(String[] args) {
T t1 = new T();
int h = t1.test(1);
System.out.println(h);
}
}
猴子吃桃
class T {
public int test(int n){
if (n == 10){
return 1;
}else if(n >=1 && n <= 9){
return (test(n + 1) + 1) * 2;
}else {
return -1;
}
}
}
三.老鼠出迷宫
思路:
1.找出迷宫路径
2.如果找到返回true,否则为false
3.map就是二维数组表示迷宫
4.i,j表示初始位置,初始位置为1,1
5.(6,5)上的值为2,表示走出迷宫,结束递归,否则就继续find
6.策略:下右上左
//1.创建迷宫
//2.先规定 map 数组的元素值:0 可以走 1 表示障碍物
// 2 表示可以走 3 表示不可以走通
int[][] map = new int[8][7];
//3.将上下的两行设置为1
for (int i = 0; i < 7; i++) {
map[0][i] = 1;
map[7][i] = 1;
}
//4.左右两列设置为1
for (int i = 0; i < 8; i++) {
map[i][0] = 1;
map[i][6] = 1;
}
//(4,2) (4,3)表示为障碍物
map[3][1] = 1;
map[3][2] = 1;
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[i].length; j++) {
System.out.print(map[i][j] + " ");
}
System.out.println();
}
T t = new T();
t.findway(map,1,1);
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[i].length; j++) {
System.out.print(map[i][j] + " ");
}
System.out.println();
}
//老鼠出迷宫
class T{
public boolean findway(int[][] map,int i ,int j){
if(map[6][5] == 2){
return true;
} else {
if (map[i][j] == 0){
//假定可以走通
map[i][j] = 2;
//使用策略,来确定该位置是否真的能走通
if (findway(map,i + 1,j)){//下
return true;
}else if (findway(map,i,j+1)){//右
return true;
}else if (findway(map,i - 1,j)){//上
return true;
}else if (findway(map,i ,j-1)){//左
return true;
}else {
map[i][j] = 3;
return false;
}
} else {//map=1,2,3
return false;
}
}
}
}
添加障碍物(3,3)可以体现出回溯显现,代码如下
//1.创建迷宫
//2.先规定 map 数组的元素值:0 可以走 1 表示障碍物
// 2 表示可以走 3 表示不可以走通
int[][] map = new int[8][7];
//3.将上下的两行设置为1
for (int i = 0; i < 7; i++) {
map[0][i] = 1;
map[7][i] = 1;
}
//4.左右两列设置为1
for (int i = 0; i < 8; i++) {
map[i][0] = 1;
map[i][6] = 1;
}
//(4,2) (4,3)表示为障碍物
map[3][1] = 1;
map[3][2] = 1;
map[2][2] = 1;
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[i].length; j++) {
System.out.print(map[i][j] + " ");
}
System.out.println();
}
T t = new T();
t.findway(map,1,1);
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[i].length; j++) {
System.out.print(map[i][j] + " ");
}
System.out.println();
}
//老鼠出迷宫
class T{
public boolean findway(int[][] map,int i ,int j){
if(map[6][5] == 2){
return true;
} else {
if (map[i][j] == 0){
//假定可以走通
map[i][j] = 2;
//使用策略,来确定该位置是否真的能走通
if (findway(map,i + 1,j)){//下
return true;
}else if (findway(map,i,j+1)){//右
return true;
}else if (findway(map,i - 1,j)){//上
return true;
}else if (findway(map,i ,j-1)){//左
return true;
}else {
map[i][j] = 3;
return false;
}
} else {//map=1,2,3
return false;
}
}
}
}
运行结果
从图可以看出,起始点(1,1)先下移动到(2,1),此时老鼠无法移动,所有回溯到上一位置向右移动。
四.汉诺塔问题
问题描述:汉诺塔(Tower of Hanoi)源于印度传说中,大梵天创造世界时造了三根金钢石柱子,其中一根柱子自底向上叠着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
思路:将A塔上的盘分为两部分,上半部分(num - 1)个盘和最小面的盘
第一步:将上半部分的盘从A移动到B,通过C
第二步:将最下面的盘从A移动到C
第三步:将上半部分的盘从B移动到C,通过A
Tower t = new Tower();
t.move(3,'A','B','C');
//汉诺塔
class Tower{
//方法
//num表示要移动的个数,abc表示塔
public void move(int num,char a,char b,char c){
if (num == 1){
System.out.println(a + "->" + c);
}else {
//如果有多个盘,可以看成两部分,最下面和上面(num - 1)个盘
//(1)先移动上部分(num - 1)个盘到b,借助c
move(num - 1,a , c, b);
//(2)把最小面的盘移动到c
System.out.println(a + "->" + c);
//(3)再把b塔上(num - 1)个盘移动到c,借助a
move(num - 1 ,b , a, c);
}
}
}