用棧+回溯+非遞迴解決N皇后問題
問題及程式碼:
/*
* Copyright (c) 2016, 煙臺大學計算機與控制工程學院
* All rights reserved.
* 檔名稱:queen.cpp
* 作 者:單昕昕
* 完成日期:2016年4月4日
* 版 本 號:v1.0
*/
#include <iostream>
#include <malloc.h>
#include <cstdio>
#include <cmath>
using namespace std;
const int MaxSize=400;
typedef struct linknode//順序棧
{
int data[MaxSize];
int top;
} SqStack;
SqStack *st;
void initStack(SqStack *&s)//初始化
{
s=(SqStack *)malloc(sizeof(SqStack));
s->top=-1;
}
bool Push(SqStack *&s,int e)//壓入棧
{
if(s->top==MaxSize-1)
return false;
s->top++;
s->data[s->top]=e;
return true;
}
bool Pop(SqStack *&s)//移除棧頂元素
{
if(s->top==-1)
return false;
s->top--;
return true;
}
bool GetTop(SqStack *s,int &e)//取棧頂元素
{
if(s->top==-1)
return false;
e=s->data[s->top];
return true;
}
bool StackEmpty(SqStack *s)//判斷棧是否為空
{
return(s->top==-1);
}
void DestroyStack(SqStack *&s)//銷燬棧
{
free(s);
}
bool Check(int *qu, int t)//能放返回真,否則為假
{
int i;
for(i=0; i<t; i++)//逐行判斷
if(qu[i]==qu[t]||abs(t-i)==abs(qu[t]-qu[i]))//在同一列或對角線
return false;
return true;
}
void Show(int *qu, int len,int Count)
{
int i;
cout<<"第"<<++Count<<"個解:";
for(i=0; i<len; i++)//i是行數
cout<<"("<<i<<", "<<qu[i]<<") ";
cout<<endl;
}
int main()
{
initStack(st);//初始化
cout<<"皇后問題(n<20) n=";
int n;
cin>>n;//輸入皇后數目
cout<<n<<"皇后問題求解如下:"<<endl;
int cnt=0,row=0;//問題的解的數目、行
int *queen = new int[n];//開闢動態陣列儲存每行皇后的列位置
queen[0]=-1;//最開始把首元素置為-1
Push(st,0);//把首位置壓入棧
while(!StackEmpty(st))//棧非空
{
GetTop(st,row);//row是當前棧頂元素值
queen[row]++;//嘗試下一列
if(queen[row]>=n)//當前行的所有n列都已經嘗試過,但是皇后沒有擺放成功
Pop(st);//棧頂元素出棧,相當於回溯到上一行
else
{
if(Check(queen,row))//檢查,如果能在該位置放皇后
{
if(row==n-1)//試探到第n行
{
Show(queen,n,cnt);//輸出皇后位置
cnt++;//解法加一
}
else//仍需要試探
{
queen[row+1]=-1;//標記-1
Push(st,row+1);//皇后的位置壓入棧
}
}
}
}
delete []queen;//釋放動態陣列
free(st);//銷燬棧
return 0;
}
執行結果:
思路:
queen[row]陣列記錄第row行上皇后的列位置;
st棧記錄當前行數;
從第0行開始,依次試探0-n-1列;
當row==n-1說明全部成功放置皇后;
當queen[row]>=n說明當前行下,各列試探完畢,都不能成功放置,所以要回溯到上一行,將當前行出棧。
相關文章
- 回溯法(排列樹)解決八(N)皇后問題
- js使用遞迴回溯法解八皇后問題程式碼分享JS遞迴
- 原:八皇后問題的遞迴和非遞迴Java實現遞迴Java
- 使用回溯演算法解決N皇后問題以及間隔排列問題演算法
- N皇后問題
- 資料結構和演算法——遞迴-八皇后問題(回溯演算法)資料結構演算法遞迴
- Python 八皇后解法(非遞迴版本)Python遞迴
- 八皇后之回溯法解決
- 遞迴解決全排列問題遞迴
- leetcode題解(遞迴和回溯法)LeetCode遞迴
- 遞迴思想----解決飲料問題遞迴
- Josephus問題解決方法五(遞迴)遞迴
- C#資料結構與演算法系列(十四):遞迴——八皇后問題(回溯演算法)C#資料結構演算法遞迴
- 漢諾塔非遞迴棧程式碼遞迴
- 從八皇后問題到回溯演算法演算法
- 揹包問題的遞迴與非遞迴演算法遞迴演算法
- N皇后問題(各種優化)優化
- 國際象棋“皇后”問題的回溯演算法演算法
- 遞迴和非遞迴分別實現求n的階乘遞迴
- c++迷宮問題回溯法遞迴演算法C++遞迴演算法
- 回溯和遞迴實現迷宮問題(C語言)遞迴C語言
- 第七章 遞迴、DFS、剪枝、回溯等問題 ------------- 7.3 題解:機器人走方格問題遞迴機器人
- 回溯法解決迷宮問題
- 回溯法解決喝酒問題 (轉)
- 快速排序【遞迴】【非遞迴】排序遞迴
- 遞迴轉非遞迴 棧模擬 Recursive to Non-recursive stack simulated 總結遞迴
- Leetcode 通過率最高的困難題 N皇后 II 【回溯解法-剪枝】LeetCode
- leetcode演算法題解(Java版)-9-N皇后問題LeetCode演算法Java
- 經典n皇后問題java程式碼實現Java
- 以Top-Down思維去解決問題——遞迴遞迴
- Java解決遞迴造成的堆疊溢位問題Java遞迴
- 回溯法解決全排列問題總結
- 每日一題之拉低通過率 回溯演算法 leetcode 51 N皇后每日一題演算法LeetCode
- 樹3-二叉樹非遞迴遍歷(棧)二叉樹遞迴
- 棧實現遞迴遞迴
- 棧Stack——遞迴替身?遞迴
- hibernate 1 + N 問題解決
- 遞迴路徑問題遞迴