回溯法应用之n皇后问题

在n行n列的棋盘上,如果两个皇后位于棋盘上的同一行或者同一列或者同一对角线上,则称他们为互相攻击。现要求找出使n元棋盘上的n个皇后互不攻击的所有布局,即是n皇后问题

package 数据结构及算法.回溯法应用之n皇后问题;

import java.util.Iterator;

import 数据结构及算法.回溯法.Application;
import 数据结构及算法.回溯法.Position;

public class Queen implements Application{
    private int[][]grid;
    private int[][]path;
    public Queen(int n){
    	this.grid=new int[n][n];
    	this.path=new int[n][2];
    	for(int i=0;i<n;i++){
    		for(int j=0;j<n;j++){
    			this.grid[i][j]=0;
    		}
    	}
    }
	@Override
	public boolean valid(Position pos) {
		if(this.grid[pos.getRow()][pos.getColumn()]==0)
		return true;
		return false;
	}

	@Override
	public void record(Position pos) {
		for(int i=0;i<this.grid.length;i++){
			if(i!=pos.getColumn())
			    this.grid[pos.getRow()][i]+=1;//横
			if(i!=pos.getRow())
				this.grid[i][pos.getColumn()]+=1;//竖		
		}
		int x=pos.getRow()-1;
		int y=pos.getColumn()-1;
		while(x>=0&&y>=0){//左上
			this.grid[x][y]+=1;
			x--;
			y--;
		}
		x=pos.getRow()+1;
		y=pos.getColumn()-1;
		while(x<this.grid.length&&y>=0){//左下
			this.grid[x][y]+=1;
			x++;
			y--;
		}
		x=pos.getRow()-1;
		y=pos.getColumn()+1;
		while(y<this.grid.length&&x>=0){//右上
			this.grid[x][y]+=1;
			x--;
			y++;
		}
		x=pos.getRow()+1;
		y=pos.getColumn()+1;
		while(x<this.grid.length&&y<this.grid.length){//右下
			this.grid[x][y]+=1;
			x++;
			y++;
		}
		this.grid[pos.getRow()][pos.getColumn()]+=2*this.grid.length;
	}

	@Override
	public boolean done(Position pos) {
		if(pos.getRow()==this.grid.length-1)
			return true;
		return false;
	}

	@Override
	public void undo(Position pos) {
		for(int i=0;i<this.grid.length;i++){
			if(i!=pos.getColumn())
			    this.grid[pos.getRow()][i]-=1;//横
			if(i!=pos.getRow())
				this.grid[i][pos.getColumn()]-=1;//竖		
		}
		int x=pos.getRow()-1;
		int y=pos.getColumn()-1;
		while(x>=0&&y>=0){//左上
			this.grid[x][y]-=1;
			x--;
			y--;
		}
		x=pos.getRow()+1;
		y=pos.getColumn()-1;
		while(x<this.grid.length&&y>=0){//左下
			this.grid[x][y]-=1;
			x++;
			y--;
		}
		x=pos.getRow()-1;
		y=pos.getColumn()+1;
		while(y<this.grid.length&&x>=0){//右上
			this.grid[x][y]-=1;
			x--;
			y++;
		}
		x=pos.getRow()+1;
		y=pos.getColumn()+1;
		while(x<this.grid.length&&y<this.grid.length){//右下
			this.grid[x][y]-=1;
			x++;
			y++;
		}
		this.grid[pos.getRow()][pos.getColumn()]-=2*this.grid.length;
	}
	
	public String toString(){
		String result="";
    	for(int i=0;i<this.grid.length;i++){
    		for(int j=0;j<this.grid[0].length;j++){
    			if(this.grid[i][j]==2*this.grid.length)
    				result+="*"+" ";
    			else
    				result+=this.grid[i][j]+" ";
    			
    		}
    		result+="\n";
    	}
    	return result;
    }

	@Override
	public Iterator iterator(Position pos) {
		
		return new QueenIterator(pos,this.grid.length);
	}
    private class QueenIterator implements Iterator{
    	private int size;
    	private int count=0;
    	private int row;
    	//private int col;
        public QueenIterator(Position pos,int queenGridLength){
        	 this.row=pos.getRow();
        	 //this.col=pos.getColumn();
        	 this.size=queenGridLength;
        }
		@Override
		public boolean hasNext() {
			return count<this.size;
		}

		@Override
		public Object next() {
			Position nextPos=new Position(this.row+1,count); 
			count++;
			return nextPos;
		}

		@Override
		public void remove() {
			throw new UnsupportedOperationException();
		}
    	
    }
}

初始情况是整个棋盘每个位置初始值为0,public boolean valid(Position pos)中判断为0 有效
在public void record(Position pos)中我让该位置为中心的横竖斜的方向上每个位置之加1,该位置加2*this.grid.length;
public void undo(Position pos),撤销时与上是逆过程;

private class QueenIterator implements Iterator为内部类,记录某位置的下一行可选位置,



一下是测试程序:
package 数据结构及算法.回溯法应用之n皇后问题;

import java.util.Iterator;
import java.util.Scanner;

import 数据结构及算法.回溯法.Application;
import 数据结构及算法.回溯法.BackTrack;
import 数据结构及算法.回溯法.Position;


public class QueenTest {
	
    private int n;
    public QueenTest(){
    	Scanner sc=new Scanner(System.in);
    	String  prompt="请输入皇后的大于3的维数!";
    	System.out.println(prompt);
    	this.n=sc.nextInt();
    	pocessInput();
    }
	
	public void pocessInput() {
		
		Application app=new Queen(n);
		BackTrack backTrack=new BackTrack(app);
		
		println("开始为:");
		println(app.toString());
		Position pos=new Position(-1,0);
		Iterator itr=app.iterator(pos);
		int count=0;
		while(itr.hasNext()){
			Position startPosition=(Position) itr.next();
			app.record(startPosition);
			if(backTrack.tryToSolve(startPosition)){
				println("success");
				count++;
				println("第"+count+"个满足的为:");
				println(app.toString());
				app=new Queen(this.n);
				backTrack=new BackTrack(app);
			}
			else{
				app=new Queen(this.n);
				backTrack=new BackTrack(app);
				println("failure!");
			}
			
		}
		
	}
	
	public void println(String s){
		System.out.println(s);
	}
	public static void main(String[]args){
		new QueenTest();
	}
}


测试时可找到从第一排每个位置开始的可能的n皇后结果,还有什么不妥的地方,欢迎拍砖

你可能感兴趣的:(问题)