约瑟夫环问题(循环单链表的实现)

       
   <h1> <pre name="code" class="java">/*<span style="font-size:18px;">                     <em><span style="font-weight: normal;"> </span><span style="font-size:24px;">约瑟夫环问题  </span></em>                                  
                   1,问题描述:
            设有1,2,3.......N的n个人围成一个圆,每个人都持有一个密码m从第一人开始,报数到第m时停止报数。报m的人出圈,再从下一个人重新开始报数, 报到m的是停 止报数,报m的出圈.....直到所有人出圈为止。当任意给出定制n和m时,求n个人的出圈的次序; 

           2,基本思路:
         (1)建立数据模型,确定存贮结构。
         (2)对任意的n个人,密码为m实现约瑟夫环问题;
         (3)出圈的顺序可以依次输出或者放在一个数组中;
       ....................................................................................
       代码实现:
      ....................................................................................
*/
       "Linklist.h;"
      struct Node
      {
       int Date;
      Node* next;
     };
    class Linklist
    {
     Node* first;
     Node* rear;
    int n;//记录实际人数;
    int m;
    public:
   Linklist();
   ~Linklist();
   void add();
   void show();
   void del();//以上实现Linklist的基本操作;
   void serect();//约瑟夫环的实现
   int getserect();
   int getn();
   void method();
   } ;
          
    "Linklist实现.cpp"
  #include<iostream>
  #include"Linklist.h"
   using namespace std;
  Linklist::Linklist()
  {
    cout<<"请输入约瑟夫环中人数为:"<<endl;
cin>>n;
if(n<=0)
throw "环的长度不能为0或者负数";


Node* p=first,*p1;
first=new Node();
p1=first;
first->Date=1;
int count=1;
while(count<n)
{
count++;
p=new Node();
p->Date=count;
p1->next=p;
p1=p;
    }
rear=p1;
p1->next=first;
}
  Linklist::~Linklist()
  {
 Node *p=first;
 for(int i=1;i<=n;i++)
 {
 p=first;
 first=first->next;
 delete p;
 }
   }
   void Linklist::serect()
{
cout<<"输入密码"<<endl;
cin>>this->m;
}
     int Linklist::getserect()
    {
 return m;
      }
    int Linklist::getn()
     {
  return n;
    }
   void Linklist::add()
    {
  int a=0;
  cout<<"请输入要在环中添加的人数"<<endl;
  cin>>a;
  if(a<=0)
       throw "增加人数不能为0或者负数";
  int count=n;
  n+=a;
  Node* p,*p1=rear;


 while(count<n)
 {
 count++;
 p=new Node();
 p->Date=count;
 p1->next=p;
 p1=p;
       }
 rear=p1;
 p1->next=first;


 
    }
     void Linklist::del()
 {
int a=0;
cout<<"请输入你要在环中删除几个人"<<endl;
cin>>a;
if(a<0||a>n)
throw "删除人数不能为0或者负数";
int count=n;
n=n-a;
Node* p=first;
while(p->Date!=n)
{  
p=p->next;
   }
rear=p;
p->next=first;

        }
       void Linklist::show()
{
Node*p=first;
 /* for(int i=1;i<=n;i++)
  {
  cout<<"第"<<i <<"个节点的Date值(排号)是"<<p->Date<<endl;
  p=p->next;
  }*/
  cout<<p->Date<<endl;
  for(p=first->next;p!=first;p=p->next)
  {
  cout<<p->Date<<endl;
  }
}
      
      void Linklist::method()   //约瑟夫环实现细节;
{
       int count=2;
  Node* pre=first;
  Node* p=first->next;
  while(p!=pre)
  {
         if(count==m)
{
cout<<p->Date<<endl;
pre->next=p->next;//
count=0;//
}
else
{
            pre=p;
p=p->next;
count++;
}
       }
  cout<<p->Date<<endl;
  delete p;
}

        "maintest.cpp"
        #include<iostream>
        #include"Linklist.h"
        using namespace std;
       int main()
      {
        Linklist list;
list.serect();
//list.show();
cout<<"人数为:"<<list.getn()<<"的约瑟夫环 "<<endl;
cout<<"密码是"<<list.getserect()<<endl;
cout<<".............................."<<endl;
cout<<endl;
cout<<"输出偏号依次为:"<<endl;
    cout<<endl;
    cout<<".............................."<<endl;
list.method();
system("pause");
return 0;
     }</span>

 

       
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值