JAVA代码实现8皇后问题

8皇后问题

最近在学习数据结构中的递归算法,并且使用递归思想学习了著名的8皇后问题。

  • 先谈谈自己对递归的理解吧。递归算法就是程序不断的调用自身的过程,递归的过程中,一定要注意两点:1.一定要有终止递归的条件;2.一定要不断的逼近递归的终止条件。程序每次调用自身,就会在调用处重新开辟一个栈空间,如果调用的参数是基本数据类型,那么这个栈空间会将参数作为局部变量存放,只供当前栈空间使用。如果调用的参数是引用数据类型,那么会将该参数存放在堆空间中成为成员变量供整个程序使用。当达到递归终止条件时,会将结果返回给上一次递归的位置,直至返回给第一次递归的位置,然后继续代码继续向下执行。

  • 8皇后问题的规则是:在一个8*8大小的棋盘上,每行放置一个皇后,一共放置8个皇后,这8个皇后之间要保证:1.不在同一列;2.不在同一斜线、反斜线上。问共有多少种摆法?

  • 8皇后问题的解决思路:
    1.将第一个皇后放在第一行第一列上;
    2.之后将每个皇后从下一行的第一列开始放置,然后判断是否与之前的皇后有冲突;
    3.如果有冲突,就放在下一列上,继续判断;
    4.如果当前皇后在8列上都与之前的皇后有冲突,就将上一个皇后往所处行的下一列放置(回溯);
    5.反复执行2-4步,直至开始放置第9个皇后时,终止递归,跳出方法;

  • 8皇后问题的第一种解决方式是定义一个88的二维数组模拟棋盘,规定88棋盘没有放置皇后的位置全部为0,放置皇后的位置全部为1。

package com.recursion;

/*
 * 使用二维数组实现8皇后问题
 *  默认棋盘初始化全为0,每放一个皇后,该位置置为1
 */
public class Queen8Demo3 {

	// 表示8*8棋盘
	static int[][] array = new int[8][8];
	// 计数
	static int count = 0;

	public static void main(String[] args) {
		put(0);
		System.out.printf("一共有%d种解法\n", count);

	}

	// 摆放皇后
	public static void put(int n) {
		if (n == 8) {
			System.out.println("第" + count + "种解法");
			print();
			return;
		}
		for (int i = 0; i < 8; i++) {
			//每次将当前行上的皇后清空
			for (int j = 0; j < 8; j++) {
				array[n][j] = 0;
			}
			
			// 如果不冲突
			if (judge(n, i)) {
				// 每次先将第n个皇后放在第n行的第一列
				array[n][i] = 1;
				put(n + 1);
			}
		}
	}

	// 每次放一个皇后,就判断是否与之前的皇后在同一列或者同一斜线
	public static boolean judge(int n, int y) {
		
		// 判断是否在同一列上
		for (int i = n; i >= 0; i--) {
			if (array[i][y] == 1) {
				return false;
			}
		}
		// 判断从右上到左下的斜线方向
		for (int i = n, j = y; i >= 0 && j >= 0; i--, j--) {
			if (array[i][j] == 1) {
				return false;
			}
		}
		// 判断左上到右下的斜线方向
		for (int i = n, j = y; i >= 0 && j < array.length; i--, j++) {
			if (array[i][j] == 1) {
				return false;
			}
		}
		return true;
	}

	// 打印棋盘
	public static void print() {
		count++;
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 8; j++) {
				System.out.print(array[i][j] + " ");
			}
			System.out.println();
		}
	}

}

  • 8皇后问题的第二种解决方式是通过创建一个长度为8的一维数组,该数组的下标表示棋盘的第几行,也代表第几个皇后,数组中每个位置上的具体数组表示皇后放在该行的第几列
package com.recursion;
/*
 * 8皇后问题,用一维数组实现,下标表示第几行,也就是第几个皇后,值代表第几列
 */
public class Queen8Demo2 {

	//创建一个长度为8的数组,用来存放皇后的位置
	static int[] array=new int[8];
	//计数
	static int count=0;
	public static void main(String[] args) {
		put(0);
		System.out.printf("共有%d种摆法\n",count);

	}
	
	//摆放皇后,n表示摆放第n+1个皇后
	public static void put(int n) {
		//如果n=8,说明是第九个皇后,也就是前8个皇后已经摆好了
		if(n==8) {
			print();
			return;
		}
		//否则,现在开始摆放皇后
		//从每行的第一列开始放皇后,每放一个皇后就要判断是否与已经放好的皇后冲突
		for (int i = 0; i < 8; i++) {
			//先把皇后放在第1列上
			array[n]=i;
			//如果不冲突,就可以摆放下一个皇后了,即再调用put()
			if (!judge(n)) {
				put(n+1);
			}
			//如果第i个位置不符合,那就判断下一下个位置
			//如果这一行的8个位置都不符合,那就重新摆放上一行的皇后
		}
		
	}
	
	//判断每次摆放的位置是否在同一列或者在同一斜线上
	public static boolean judge(int n) {
		//每次摆放的时候需要跟前面的n-1个皇后比较
		for (int i = 0; i < n; i++) {
			//如果在同一列,或者在同一斜线上,那就返回true
			if(array[i]==array[n]||Math.abs(n-i)==Math.abs(array[n]-array[i])) {
				return true;
			}
		}
		return false;
	}
	
	//打印数组
	public static void print() {
		count++;
		for (int i = 0; i < array.length; i++) {
			System.out.print(array[i]+" ");
		}
		System.out.println();
	}

}

以上是自己对递归思想和8皇后问题的理解,如有错误之处还望指出,我会及时改正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值