N皇后问题求解算法

大学时C++程序设计课程的作业题目。呵呵!

N皇后问题(含八皇后问题的扩展,规则同八皇后):在N*N的棋盘上,放置N个皇后,要求每一横行每一列,每一对角线上均只能放置一个皇后,求解可能的方案及方案数。

下面程序利用堆栈数据结构,使用回溯法求出所有可行解。

/*
 Copyright (c) 2006, Computing Center of IHEP, Beijing, China
 Aigui.LIU@ihep.ac.cn
 链式结构堆栈类的类模板实现及用堆栈类求解N皇后问题 
 编写:089906-36@NUAA 刘爱贵  
*/

#include "iostream.h"
#include "math.h"
#define  TRUE     1
#define  FALSE    0
#define  ERROR   -1
typedef int Status;
//用模板实现的链式结构堆栈类
template <class T>
class stack{
        private:
        struct link{
                T data;                 //结点数据域
                link *next;             //下一结点指针
                link(T Data,link* Next){//结构体构造函数
                data=Data;
                next=Next;
                }
        }*head;                    //堆栈顶指针
        public:
                stack();               //构造函数(初始化栈)
           ~stack();               //析构函数(销毁栈)
            void  push(T Data);    //压栈操作
                T gettop()const;       //取栈顶元素
                T pop();               //出栈操作
                T getvalue(int index); //返回栈底开始第INDEX个栈中值
                void  traverse(int n); //遍历栈 N个数换行
                int   empty();         //判断栈是否为空,1是,0非
                int   sizeofstack();   //返回栈的大小
                void  clear();         //清空栈
};
//N皇后类
class queen{
private:
        stack<int>* qStack;            // 求解中所用数据结构:堆栈
public:
        queen();                       //构造函数
       ~queen();                       //析构函数
        Status Place(int k);           // 判断当前行K列是否可以可以放置皇后
        Status Queen(int n);           //求出所有解
};
//类模板成员函数的实现
template<class T> stack<T>::stack()//构造函数
{
        head=0;
}
template<class T> stack<T>::~stack()//析构函数
{
        link* cursor=head;
        while(head)
        {
                cursor=cursor->next;
                delete head;
                head=cursor;
        }
}
template<class T>void stack<T>::push(T Data)//压栈操作
{
        head=new link(Data,head);
}
template<class T>T stack<T>::gettop()const//取栈顶元素
{
        return head->data;
}
template<class T>T stack<T>::pop()//出栈操作
{
        if(head==0)return 0;
        T result=head->data;
        link* oldhead=head;
        head=head->next;
        delete oldhead;
        return result;
}
template <class T>T stack<T>::getvalue(int index)//返回栈底开始第INDEX个栈中值
{
    link *cursor=head;
        int i=1;
        int stacklen=sizeofstack();
        if(index<=0||index>stacklen)return 0;
    while(i<=(stacklen-index))
        {
                cursor=cursor->next;
                i++;
        }
        return cursor->data;
}
template <class T> void stack<T>::traverse(int n)//遍历栈
{
        link * cursor=head;
        int iEnterSign=1;//换行标识
        while(cursor)
        {
                cout<<cursor->data<<"  ";
                if(iEnterSign%n==0)cout<<endl;
                cursor=cursor->next;
                iEnterSign++;
        }
    if((iEnterSign-1)%n!=0)cout<<endl;
}
template <class T>int stack<T>::empty()         //判断栈是否为空,1是,0非
{
        return head==0?1:0;
}
template <class T>int stack<T>::sizeofstack()   //返回栈的大小
{
        int size=0;
        link *cursor=head;
        while(cursor)
        {
                cursor=cursor->next;
                size++;
        }
        return size;
}
template<class T> void stack<T>:: clear()         //清空栈
{
        link *cursor=head;
        while(cursor&&cursor->next)
        {
        cursor=cursor->next;
                delete head;
                head=cursor;
        }
}
//N皇后类成员函数的实现
queen::queen()                       //构造函数
{
   qStack=new(stack<int>);
}
queen:: ~queen()                     //析构函数
{
        delete qStack;
}
Status queen::Place(int k)           // 判断当前行K列是否可以可以放置皇后
{
  int i=1,j,e;
  j=qStack->sizeofstack()+1;
  while(i<j)
   {
     e=qStack->getvalue(i);
     if((k==e)||(abs(i-j)==abs(e-k))) return FALSE;
     i++;
   }
  return TRUE;
}
Status queen::Queen(int n)           //回溯法求出N皇后所有解
{
  int k,m=0,e;
  if(n<4)return ERROR;
  k=1;
  while(!qStack->empty()||k<=n)
      {
        while((k<=n)&&(!Place(k)))k++;
        if(k<=n)
          {
            qStack->push(k);
            if(qStack->sizeofstack()==n)
            {
                  m++;
                  qStack->traverse(n);
                  e=qStack->pop();
                  k=e;
                  k++;
            }
            else k=1;
          }
        else
         {
           e=qStack->pop();
           k=e;
           k++;
         }
  }
  cout<<"There are "<<m<<" ways"<<endl;
  return TRUE;
}
void main(void)//程序入口函数
{
        //堆栈操作示例
        cout<<"堆栈操作示例:"<<endl;
        stack<int> *sample=new(stack<int>);
        sample->empty()==1?cout<<"Stack is empty!"<<endl:cout<<"Stack is not empty!"<<endl;
    int i;

        for(i=1;i<=10;++i)sample->push(i);
    sample->traverse(10);
        sample->empty()==1?cout<<"Stack is empty!"<<endl:cout<<"Stack is not empty!"<<endl;
    cout<<"Size of the Stack is:"<<sample->sizeofstack()<<endl;
        cout<<"Top of stack is:"<<sample->gettop()<<endl;

        for(i=1;i<=5;++i)sample->pop();
        sample->traverse(10);
        sample->empty()==1?cout<<"Stack is empty!"<<endl:cout<<"Stack is not empty!"<<endl;
    cout<<"Size of the Stack is:"<<sample->sizeofstack()<<endl;
        cout<<"Top of stack is:"<<sample->gettop()<<endl;
        //用堆栈回溯实现的八皇后问题求解
        cout<<"八皇后问题解:"<<endl;
        queen eightqueen;
        eightqueen.Queen(8);
        cout<<"链式结构堆栈类的类模板实现及用堆栈类求解八皇后问题"<<endl;
        cout<<"编写:089906-36@NUAA Aigui.LIU   2002年10月12日完成";
        cin.get();
}//程序结束

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值