`

数据结构应用回顾之Stack(三) N皇后问题 非递归实现

 
阅读更多

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),

 

分享到:
评论

相关推荐

    数据结构:栈的应用-递归函数转非递归函数

    总结一下,通过使用数据结构中的栈,我们可以将效率较低的递归函数转换为非递归函数,提高计算效率,减少内存消耗,防止堆栈溢出。在实际编程中,尤其是在处理大数据量或需要高效运行的算法时,这样的优化是非常重要...

    快速排序 --- 非递归实现

    快速排序是一种高效的排序算法,由英国计算机科学家C.A.R....总的来说,这个压缩包提供了一个非递归实现快速排序的完整示例,通过自定义栈的数据结构,实现了快速排序算法,适用于理解和学习快速排序的非递归实现方式。

    数据结构-非递归遍历二叉树

    非递归遍历二叉树是一种不依赖递归函数来访问树的所有节点的方法,它通常通过栈或队列等数据结构来实现。下面我们将详细探讨非递归遍历二叉树的先序、中序和后序策略。 先序遍历是二叉树遍历的一种方法,其顺序为:...

    快速选择非递归与递归算法实现

    空间复杂度方面,非递归实现主要取决于分区操作和栈的使用,而递归实现则依赖于递归深度,一般情况下都是O(log n)。 在实际编程中,可以根据具体需求选择非递归或递归实现。非递归版本更适合内存有限或者递归深度...

    汉诺塔的非递归实现,c++

    总之,非递归的汉诺塔问题C++实现是一种创新的解决方案,它利用数据结构来避免递归调用的开销,展示了算法设计的灵活性和创造性。通过学习这种实现,你可以更深入地理解数据结构、算法以及它们在实际编程中的应用。

    N皇后问题 数据结构 用回溯法和栈解决 c++

    N皇后问题是计算机科学中经典的问题之一,主要涉及数据结构和算法设计。该问题要求在n×n的棋盘上放置n个皇后,使得任意两个皇后都无法在同一行、同一列或同一对角线上互相攻击。本问题通常用作展示回溯法和深度优先...

    汉诺塔-汉诺塔的非递归实现源码和原理讲解

    总之,非递归汉诺塔问题的解决方法利用了栈的数据结构,通过迭代实现盘子的有序移动,从而避免了递归可能导致的堆栈溢出问题,尤其适用于处理大规模问题。理解和实现这个算法有助于深化对数据结构和算法的理解,以及...

    C语言实现二叉树的前序遍历(非递归)

    通过以上分析,我们可以看到,非递归的前序遍历不仅避免了递归可能带来的栈溢出问题,而且通过巧妙利用栈的数据结构,能够有效地实现二叉树的遍历。这一方法在处理大规模数据或深度较大的二叉树时尤为有用。在实际...

    数据结构中stack的实现

    理解栈的概念和实现方法对于学习算法和解决编程问题至关重要,例如在递归、表达式求值、括号匹配、深度优先搜索等问题中都有栈的身影。通过这个C语言实现的栈程序,你可以更好地理解栈的工作原理,并将其应用于各种...

    二叉树非递归实现源码(C、C++、JAVA)

    二叉树是一种重要的数据结构,它由节点组成,每个节点有两个...非递归实现二叉树操作需要对数据结构有深入理解,通过迭代的方式,可以提高程序的性能和可读性。对于学习和提升算法能力,这些源码是非常宝贵的参考资料。

    链式栈实现递归和非递归迷宫路径求解

    在IT领域,尤其是在算法设计和数据结构应用中,迷宫路径求解是一个经典的挑战。本话题将深入探讨如何使用链式栈实现递归和非递归的迷宫路径求解方法,结合Java编程语言,以及深度优先搜索(DFS)策略。 首先,我们...

    非递归实现二叉树的算法

    ### 非递归实现二叉树的遍历算法 #### 概述 在计算机科学中,二叉树是一种常用的数据结构,它在许多实际应用中都有广泛的应用,如文件系统、编译器的设计等。通常,二叉树的遍历(前序、中序、后序)可以采用递归...

    N皇后问题求解(C++)

    在这个特定的案例中,我们看到的是一个使用C++编程语言,特别是栈数据结构来解决N皇后问题的实现。 首先,让我们详细解释一下回溯法。回溯法是一种试探性的解决问题的方法,它尝试逐步找到问题的解决方案。当它发现...

    C++数据结构实现之Stack.zip

    在这个"C++数据结构实现之Stack"的压缩包中,我们主要关注的是栈(Stack)这一基本数据结构的C++实现。 栈是一种后进先出(Last In First Out, LIFO)的数据结构,它的操作类似于一个堆叠物品的过程,新添加的元素...

    数据结构 二叉树非递归算法

    在提供的文件名中,`main.cpp`可能是实现这些算法的主程序,`BiTree.h`包含了二叉树的定义和相关操作,而`queue.h`和`stack.h`提供了队列和栈的接口,这些都是实现非递归算法的关键数据结构。通过这些文件,我们可以...

    Java数据结构实现之Stack.zip

    本篇将重点讨论Java中栈(Stack)这一重要数据结构的实现。 栈是一种线性数据结构,遵循“后进先出”(LIFO,Last In First Out)的原则。在栈中,最后加入的元素(称为顶元素)最先被移除。栈的操作主要包括两个...

    二叉树的C++非递归实现

    在计算机科学中,二叉树是一种特殊的图结构,其中每个节点最多有两个子节点,通常称为左子节点和右子节点。二叉树广泛应用于数据存储、搜索算法...通过熟练掌握这种实现方式,开发者能够更好地应对复杂的数据结构问题。

    C语言数据结构中序遍历的非递归算法

    递归版本的中序遍历通常使用栈作为辅助数据结构,通过反复调用自身来实现。然而,非递归实现则需要我们自己管理这个过程。 非递归中序遍历通常采用迭代的方式,利用栈来保存待访问的节点。以下是一个简单的步骤概述...

    JAVA快速排序(递归实现与非递归堆栈模拟实现)

    ### JAVA快速排序(递归实现与非递归堆栈模拟实现) #### 一、递归实现的快速排序 快速排序是一种非常高效的排序算法,它的基本思想是通过一趟排序将待排记录分隔成独立的两部分,其中一部分的所有记录都比另一...

Global site tag (gtag.js) - Google Analytics