遞歸和回溯求解8皇后問題

遞歸和回溯

遞歸原理

(1)什麼是遞歸?
答:遞歸就是本身調用本身,每次調用都傳入不一樣的變量
(2)遞歸調用的機制
答:棧。當程序執行到一個方法的時候,爲該方法開闢一個獨立的棧空間用於存放該方法所用到的所有變量,若是這些變量是引用變量,那麼他們則是共享一個變量空間,其餘的變量有獨立的空間。
(3)使用遞歸的重要規則java

  • 終止條件
  • 遞歸調用過程當中逐漸向終止條件趨近,否者是死遞歸

回溯原理

(1)什麼是回溯?
答:簡單來說就是:當前的操做不符合要求時,則退回到到上一步,從新規劃當前操做的方法。算法

遞歸和回溯算法的經典應用場景

8皇后問題
問題描述: 在8*8的棋盤上擺放8個皇后,要求:全部的皇后均不能在同一行、同一列和斜對角上,求全部的擺法?
分析: 8皇后問題綜合應用了遞歸調用和回溯的思想,逐一擺放第1個皇后一直到第8個皇后,每次擺放一個皇后的位置時候,須要判斷當前皇后的位置是否與以前全部已經擺放的皇后的位置相沖突,若是衝突,則回溯,即從新規劃上一個皇后的位置,直到知足條件位置,若是不衝突,則採用遞歸調用的思想,規劃下一個皇后的擺放位置。
解決8皇后問題的幾個關鍵點數組

  • 何時遞歸?及其遞歸的終止條件
    (1)遞歸主要是在當前皇后的擺放位置符合要求時,進行下個一個皇后位置規劃時使用遞歸,當8個皇后都擺放完成時,遞歸結束
  • 何時回溯?進行回溯的條件
    (1)在當前皇后的位置擺放不符合要求時,進行回溯,更換當前皇后的位置,直到符合要求

8皇后問題的Java代碼實現

/**
 * 8皇后問題:
 * 8*8的棋盤上,放置8個皇后,要求8個皇后不能再同一行同一列和同一對對角線上
 * 求出全部的擺法
 */
public class Queue8 {

    private int[] array=new int[8];//表示8*8的棋盤,array[n]==i;每一個皇后放一行,第n個皇后即第n行,放置在第i列
    private int count=0;//記錄總的結果數量
    public static void main(String[] args) {
        Queue8 queue8=new Queue8();
        queue8.check(0);//從第一個皇后開始遞歸
        System.out.print( queue8.count);
    }
    /**
     * 擺放第n個皇后
     * @param n
     */
    private  void check(int n){
        //使用遞歸求解:
        //遞歸的結束條件:n==8時,此時[0,7]個皇后已經擺放完成。
        if(n==8){
            print();//打印每一種結果
            return;//結束次此方法
        }
        //開始遞歸和回溯
        //遞歸發生在:不產生衝突的狀況下:check(n+1);
        //回溯發生在:產生了衝突:則當前的check(n)不成立;重現擺放至下一個位置;
        for(int i=0;i<8;i++){
            array[n]=i;//嘗試將第n個皇后擺放在第i列;
            if(judge(n)){//和第n個皇后以前的全部皇后比較,判斷當前位置是否合法
                //若是合法,進入遞歸調用,開始安排第n+1個皇后的位置
                check(n+1);
            }
            //不然的話,進入回溯環節,從新安排第n個皇后的位置即array[n]=i+1;
        }
    }
    /**
     * 判斷該皇后放置的位置是否合法
     */
    private boolean judge(int n){
        //不在同一行約束,採用array[]數組必定再也不同一行
        //不一樣同一列:array[n1]!=array[n2];
        //不在同一對角線上array[n1]-array[n2]!=n1-n2,斜率不爲1或者-1

        //當前的皇后和以前的全部皇后均要比較,只有所有符合才爲true
        for(int i=0;i<n;i++){
            if(array[n]==array[i] || Math.abs(array[i]-array[n])==Math.abs(i-n)){
                return false;
            }
        }
        return true;
    }

    /**
     * 打印擺放的結果
     */
    private void print(){
        count++;
        for(int i=0;i<8;i++){
            System.out.print(array[i]+" ");
        }
        System.out.println();//每一種結果換行
    }
}
相關文章
相關標籤/搜索