循环链表——约瑟夫问题(C++)

来源:互联网 发布:任务清单软件 编辑:程序博客网 时间:2024/04/29 13:43

#include <iostream>
using namespace std;
const maxsize=10;
class Node
{
 int dataCode;//定义数据节点
 Node *next;
};
class josephus
{
public:
 int length;
 int size;
 Node *elem;//链表中的元素
 Node *pcurrent,*ppriv;//当前节点和上一个节点
 Node *head;
 int i;//用于计数
 int j;//循环变量
 int left;//留下来的人
 int win;


public:
 void joseph(int n,int m,int s);//n个小孩,从第s个开始,数到第m个离开;函数返回最后留下的编号
 void init();
 bool empty();
 void insert();
 


};
void josephus::init()
{
 elem=new Node[maxsize];
 if(elem==NULL)
 {
  cout<<"空间申请失败!"<<endl;
  return;

 }
 else
 {
  cout<<"空间申请成功"<<endl;
  length=0;
  size=maxsize;

 }
 

}
bool josephus::empty()
{
 return length==0;
 head->next=NULL;

}
void josephus::insert()
{
 Node *newbase;
 int n,s,m;
 if(empty())
 {
  cout<<"链表为空,如下为构造有元素循环链表"<<endl;
  cin>>n;//输入小孩数量
  for(j=0;j<n-1;j++)
  {
   elem[j].dataCode=j+1;//编号
   elem[j].next=&elem[j+1];//指向下一结点

  }
  elem[n-1].dataCode =n;
  elem[n-1].next =&elem[0];
  pcurrent=&elem[s-1]//循环链表构造完成

 }
 if(*(&pcurrent)<1 || *(&pcurrent)>length+1)
 {
  cout<<"链表已满,请从新申请空间"<<endl;
  newbase=(Node *)realloc(size,sizeof(Node)*(size+maxsize));
       
  if(!newbase)
  {
   cout<<"从新申请空间失败"<<endl;

  }
        elem=newbase;


  
 }
 
}
void josephus::joseph(int n,int m,int s)
{
 init();
 insert();
 //cin>>n>>' '>>m>>' '>>s;
 if(s>n||s<1)
 {
  cout<<"开始报数的序号超过范围"<<endl;
  return -1;

 }
 //设上一个节点
 if(1==s)
 {
  ppriv=&elem[n-1];
  
 }
 else
 {
  ppriv=&elem[(s-1)-1];
 }
 //设定计数的初始值
 i=0;
 //循环的终止条件是pcurrent指向自己
 while(pcurrent->next!=pcurrent)
 {
  i++;
  if(i==m)
  {//添加测试代码,输出编号
   cout<<pcurrent->dataCode<<'/t';
   //删除一个数到m的人
   ppriv->next=pcurrent->next;
   i=0;
  }
  ppriv=pcurrent;
  pcurrent=ppriv->next;
 }
 //循环终止后,保存胜利者编号,然后释放内存
 win=pcurrent->dataCode;
 delete [n]elem;
 return win;


}
int main(void)
{
 josephus a;
 //a.init();
 a.joseph(10,8,1);
 return 0;

}