Java学习之八皇后

递归的第三个实际案例:八皇后

老师给的思路:

//1.第一个皇后先放第一行第一列;
    //2.第二个皇后放在第二行第一列、然后判断是否 OK,
    //如果不 OK,则尝试放在第二列、第三列…,直到找到一个合适的位置;
    //3.继续放置第三个皇后,还是第一列、第二列…,直到找到一个合适的位置;
    //4.依次循环下去,直到第 8 个皇后也能放在一个不冲突的位置,就算是找到了一个正确解;
    //5.当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯。本次回溯之后,
    //会即将第一个皇后放到第一列前提下的所有正确解全部得到;
    //6.然后回头从 1 开始,第一个皇后放到第一行第二列,后面继续循环执行 2、3、4 的步骤,
    //直至第一个皇后将第一行的所有列都放置过。至此,便得到了八皇后问题的所有放置解法。

我自己的理解

    //创建一个一维数组,index+1表示第(index + 1)个皇后在第(index + 1)行,
    //arr[index] = 3;表示这个皇后在第4列
    //基本思路:假定arr[0] = 0;即第一个皇后在第一列,第二个皇后在第二行即arr[1]
    //判断标准:如果:arr[0] = arr[1],那么表示两个皇后在同一列,
    //如果|arr[1]-arr[0]| = |1-0|;表示两个皇后在同一斜线上
    //假如arr[0] = 7,arr[1] = 6;判断斜线:|0-1| = |7-6|;这个时候就需要取绝对值,绝对值是非负数

第一步:

编写输出算法,代码:

int arr[] = new int[8];
	//输出算法
	public void print(){
		for(int i = 0; i < arr.length; i++){
			System.out.print(arr[i] + " ");
		}
		System.out.println();
	}

第二步:

编写判断是否冲突的代码

public boolean judge(int index){
		for(int i = 0; i < index; i++){//判断和之前的index个皇后是否冲突
			if(arr[i] == arr[index] || Math.abs(arr[index]-arr[i]) == Math.abs(index -i)){
				return false;
			}
		}
		return true;//必须放在for循环外部,
	}

放在for循环外部的原因:假如是第7个皇后,必须判断完前六个皇后都不冲突再返回true

第三步:

放置算法:即调用方法,递归

//放置算法,即在棋盘中放置第几个皇后
	public void put(int index){

		//首先判断index是否等于8
		if(index == 8){//当index等于8的时候,即第9个棋子,已经完成了8个棋子的放置
			print();//调用输出算法
			
		}else{
			for(int i = 0; i < 8; i++){
				arr[index] = i;//
				if(judge(index)){//如果返回true则继续判断
					put(index + 1);
				}

			}
		}
	}

完整代码

public class QueenTest{
	public static void main(String[] args){
		T t1 = new T();
		t1.put(0);
	}
}
class T{
	int arr[] = new int[8];
	//输出算法
	public void print(){
		for(int i = 0; i < arr.length; i++){
			System.out.print(arr[i] + " ");
		}
		System.out.println();
	}
	
	//判断算法
	public boolean judge(int index){
		for(int i = 0; i < index; i++){//判断和之前的index个皇后是否冲突
			if(arr[i] == arr[index] || Math.abs(arr[index]-arr[i]) == Math.abs(index -i)){
				return false;
			}
		}
		return true;//必须放在for循环外部,
	}
	//放置算法,即在棋盘中放置第几个皇后
	public void put(int index){

		//首先判断index是否等于8
		if(index == 8){//当index等于8的时候,即第9个棋子,已经完成了8个棋子的放置
			print();//调用输出算法
			
		}else{
			for(int i = 0; i < 8; i++){
				arr[index] = i;//
				if(judge(index)){//如果返回true则继续判断
					put(index + 1);
				}

			}
		}
	}
}



简单的内存分析图

统计共有多少种解法的代码

public class QueenTimes{
	public static void main(String[] args){
		int count = 0;
		T t1 = new T();
		count = t1.put(0);
		System.out.println("八皇后一共有" + count + "种解法");
	}
}
class T{
	int arr[] = new int[8];
	int count = 0;
	//输出算法
	public void print(){
		for(int i = 0; i < arr.length; i++){
			System.out.print(arr[i] + " ");
		}
		System.out.println();
		count ++;
	}
	
	//判断算法
	public boolean judge(int index){
		for(int i = 0; i < index; i++){//判断和之前的index个皇后是否冲突
			if(arr[i] == arr[index] || Math.abs(arr[index]-arr[i]) == Math.abs(index -i)){
				return false;
			}
		}
		return true;//必须放在for循环外部,
	}
	//放置算法,即在棋盘中放置第几个皇后
	public int put(int index){

		//首先判断index是否等于8
		if(index == 8){//当index等于8的时候,即第9个棋子,已经完成了8个棋子的放置
			print();//调用输出算法
			
		}else{
			for(int i = 0; i < 8; i++){
				arr[index] = i;//
				if(judge(index)){//如果返回true则继续判断
					put(index + 1);
				}

			}
		}
		return count;
	}
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值