递归的第三个实际案例:八皇后
老师给的思路:
//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;
- }
- }
-
-
-
