递归算法(基于JAVA实现)
递归算法,在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。
递归式方法可以被用于解决很多的计算机科学问题,因此它是计算机科学中十分重要的一个概念。
绝大多数编程语言支持函数的自调用,在这些语言中函数可以通过调用自身来进行递归。
计算理论可以证明递归的作用可以完全取代循环,因此在很多函数编程语言(如Scheme)中习惯用递归来实现循环。
递归能解决的问题:
例如:
(1)数学上:汉诺塔问题、8皇后问题、阶乘问题、迷宫问题等。
(2)算法上:归并排序、快速排序、二分查找等。
(3)对于解决栈的问题
递归的注意事项:
(1)递归必须向退出递归的条件接近,否则就会无限递归(StackOverflowError)
(2)如果方法中引用的是类型变量,那么就会共享此数据。
(3)递归方法中的局部变量是独立的,不会相互影响。
(4)执行一个递归方法时,就要创建一个独立的栈空间。
(5)当一个递归方法执行完毕时,就返回,遵循谁调用,将结果返回给谁,此时该方法执行完毕。
一、利用递归思想解决8皇后问题。
八皇后问题,是由国际西洋棋棋手马克斯·贝瑟尔于1848年提出的问题,是回溯算法的典型案例。
问题表述为:在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、
同一列或同一斜线上,问有多少种摆法?
解决思路(回溯算法):
(1)先把第一个棋子放在第一行第一列
(2)第二个皇后放在第二行第一列,此时需要进行判断此皇后与n-1前面的皇后进行判断是否冲突。
若冲突则放在第二列,第三列。。。。直到找到一个合适的点。
(3)继续把第三个皇后放在第三行第一列……进行冲突判断,直至找到合适的 。
(4)直到找到第八个棋子与前面不冲突,此时得到一个正解。
(5)然后进行回溯,到第一个棋子放在第一行第二列,重复(1)(2)(3)(4)步骤,最后得到总共的解决方案。
以下为实现代码:
package com.java;
import static sun.misc.Version.print;
public class Queen8Demo {
public static void main(String[] args) {
Queen queen = new Queen();
queen.check(0);
queen.display();
}
}
class Queen
{
int max = 8;
int[] array = new int[max];
int count = 0;
int judgeCount = 0;
public void check(int n)
{
if (n == 8)
{
print();
return;
}
for (int i = 0; i < max; i++) {
array[n] = i;
if (judge(n))
{
check(n + 1);
}
}
}
public boolean judge(int n)
{
judgeCount++;
for (int i = 0; i < n; i++) {
if (array[i] == array[n] || Math.abs(n-i) == Math.abs(array[n] - array[i]))
return false;
}
return true;
}
public void print()
{
count++;
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + "\t");
}
System.out.println();
}
public void display()
{
System.out.println("解决方法有:" + count + "种。");
System.out.println("一共处理了" + judgeCount + "遍");
}
}
二、迷宫找路问题
此时定义一个二维数组作为迷宫地图,需要从某个点出发,直至找到最后的出口。
0表示没有走过的路,1表示墙,2表示可以走的路,3表示走过的路,但走不通。
package com.java;
import java.util.Scanner;
public class Maze {
public static void main(String[] args) {
int line,column;
System.out.println("请输入要绘画的行与列");
Scanner scanner = new Scanner(System.in);
line = scanner.nextInt();
column = scanner.nextInt();
int[][] map = new int[line][column];
for (int i = 0; i < line; i++) {
map[i][0] = 1;
map[i][6] = 1;
}
for (int i = 0; i < column; i++) {
map[0][i] = 1;
map[7][i] = 1;
}
map[5][1] = 1;
map[3][2] = 1;
setWay(map,3,6);
for (int i = 0; i < column; i++) {
for (int j = 0; j < line; j++) {
System.out.print(map[i][j] + "\t");
}
System.out.println();
}
}
public static boolean setWay(int[][] map, int i, int j) {
if (map[6][5] == 2)
{
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))
{
return true;
}
else {
map[i][j] = 3;
return false;
}
} else
{
return false;
}
}
}
}