N皇后问题使用stack的非递归实现
package com.xx.dataStructure.stack; class Point { int x; int y; int value; Point(int x ,int y){ this(x,y,0); } Point(int x ,int y,int value){ this.x = x; this.y = y; this.value = value; } @Override public String toString(){ return "(" + x + "," + y + ")"; } } //求解N皇后问题的所有解 public class Queen { private int solution = 0; private int n; private Point [][] points = null; public Queen(int n) { assert (n > 0); this.n = n; this.solution = 0; points = new Point[n][n]; for(int i =0; i<n ; ++i){ for(int j =0; j<n ; ++j){ points[i][j] = new Point(i,j); } } } //point的行、列、对角线的点value +1 public static void add(Point[][] points,Point point){ //列 for(int i = 0; i < points.length ; i++ ){ points[i][point.y].value += 1; } //行 for(int i = 0; i < points.length ; i++ ){ points[point.x][i].value += 1; } //对角线 for( int i= point.x, j = point.y ;( i < points.length && j < points.length); ++i , ++j ){ points[i][j].value += 1; } for( int i= point.x, j = point.y ;( i >= 0 && j < points.length); --i , ++j ){ points[i][j].value += 1; } for( int i= point.x, j = point.y ;( i < points.length && j >= 0); ++i , --j ){ points[i][j].value += 1; } for( int i= point.x, j = point.y ;( i >= 0 && j >= 0); --i , --j ){ points[i][j].value += 1; } point.value = 1; } public static void minus(Point[][] points,Point point){ //列 for(int i = 0; i < points.length ; i++ ){ points[i][point.y].value -= 1; } //行 for(int i = 0; i < points.length ; i++ ){ points[point.x][i].value -= 1; } //对角线 for( int i= point.x, j = point.y ;( i < points.length && j < points.length); ++i , ++j ){ points[i][j].value -= 1; } for( int i= point.x, j = point.y ;( i >= 0 && j < points.length); --i , ++j ){ points[i][j].value -= 1; } for( int i= point.x, j = point.y ;( i < points.length && j >= 0); ++i , --j ){ points[i][j].value -= 1; } for( int i= point.x, j = point.y ;( i >= 0 && j >= 0); --i , --j ){ points[i][j].value -= 1; } point.value = 0; } // 能否使用非递归算法 回溯法来使时间复杂度降为多项式 public static void solveProblem0(Queen queen) { Stack<Point> stack = new Stack<Point>(100); System.out.println("开始求解"+queen.n+"皇后问题。"); Point [][] points = queen.points; int [] tags = new int[queen.n]; for(int i = 0; i < queen.n; i ++){ tags[i] = -1; } int k = 0; try { for (int i = 0; i < queen.n; ++i) { Point currentPoint = points[0][i]; stack.push(currentPoint); add(points,currentPoint); k++; while(!stack.isEmpty()){ if (k == queen.n ){ queen.solution++; stack.traverse(); Point point = stack.pop(); minus(points, point); k--; }else { Point nextP = findNextPoint(points,tags,k); if (nextP != null){ stack.push(nextP); add(points,nextP); k++; }else { Point point = stack.pop(); minus(points, point); tags[k--] = -1; } } } } } catch (Exception e) { e.printStackTrace(); } } public static Point findNextPoint(Point [][] points,int[] tags ,int k){ Point p = null; for(int q = tags[k] + 1 ; q < points.length; q++){ tags[k]++; if (points[k][q].value == 0){ p = points[k][q]; break; } } return p; } public static void main(String[] args) { solveProblem0(new Queen(1)); solveProblem0(new Queen(2)); solveProblem0(new Queen(3)); solveProblem0(new Queen(4)); solveProblem0(new Queen(5)); solveProblem0(new Queen(6)); } }
程序输出
开始求解1皇后问题。 (0,0), 开始求解2皇后问题。 开始求解3皇后问题。 开始求解4皇后问题。 (0,1),(1,3),(2,0),(3,2), (0,2),(1,0),(2,3),(3,1), 开始求解5皇后问题。 (0,0),(1,2),(2,4),(3,1),(4,3), (0,0),(1,3),(2,1),(3,4),(4,2), (0,1),(1,3),(2,0),(3,2),(4,4), (0,1),(1,4),(2,2),(3,0),(4,3), (0,2),(1,0),(2,3),(3,1),(4,4), (0,2),(1,4),(2,1),(3,3),(4,0), (0,3),(1,0),(2,2),(3,4),(4,1), (0,3),(1,1),(2,4),(3,2),(4,0), (0,4),(1,1),(2,3),(3,0),(4,2), (0,4),(1,2),(2,0),(3,3),(4,1), 开始求解6皇后问题。 (0,1),(1,3),(2,5),(3,0),(4,2),(5,4), (0,2),(1,5),(2,1),(3,4),(4,0),(5,3), (0,3),(1,0),(2,4),(3,1),(4,5),(5,2), (0,4),(1,2),(2,0),(3,5),(4,3),(5,1),