约瑟夫环程序C++循环单链表实现

约瑟夫环程序C++循环单链表实现。/
//当中的new和delete采用了重载函数。
//也采用了可利用空间表提高了系统分配和回收的速度。
//   题目:
//   编号为1,2,3。。。。N的N个人按顺时针方向坐成一圈。每个人有一个密码,一开始任选一个
//   整数作为报数上限值M,从第一个人开始按顺时针方向自1开始顺序报数。报到M时停止报数,报M
//   的人出列,将他的密码作为下一次报数的新值M,从他的顺时针方向上的下一个人开始重新从1
//  开始报数。如此下去直到所有人都出列为止。


#include <iostream>
using namespace std;
//每个人的号码和密码。
struct people
{
 int NO;
 int pass;
}node;
template <class Elem>
class Link
{
private:
 static Link<Elem>* freelist;//静态数据成员的头接点。
public:
 struct people element;
 Link* next;
 Link(people elemval,Link* nextval=NULL)
 {
  element.NO=elemval.NO;
  element.pass=elemval.pass;
  next=nextval;
 }
 Link(Link* nextval=NULL)
 {
  next=nextval;
 }
 void* operator new(size_t);// 重载new 函数。
 void operator delete(void*);//重载delete函数。
};

template <class Elem>
class LList
{
private:
 Link<Elem> *head;
 Link<Elem> *tail;
 Link<Elem> *fence;
 void init()
 {
  head=tail=fence=new Link<Elem>;
  tail->next=head->next;  //生成链表是要把它的头接点和尾接点连接起来构成循环链表。
                          //因为有一个空的头接点。所以要把他的尾接点接到头接点的下一个指针。
 }
 void removeall()
 {
  while(head!=NULL)
  {
   fence=head;
   fence=fence->next;
   delete fence;
  }
 }
public:
 LList()
 {
  init();
 }
 ~LList()
 {
  removeall();
 }
 bool insert(const people& T);
 bool remove(Elem&);
 void getOut(int&,int&);
 void prev();
 bool append(const people& T);

};

template <class Elem>
Link<Elem>* Link<Elem>::freelist=NULL;//静态数据成员的初始化。
//重载的实现。
template <class Elem>
void* Link<Elem>::operator new(size_t)
{
 if(freelist==NULL)
  return ::new Link;
 Link<Elem>* temp=freelist;
 freelist=freelist->next;
 return temp;
}
//重载的实现
template <class Elem>
void Link<Elem>::operator delete(void* ptr)
{
 ((Link<Elem>*)ptr)->next=freelist;
 freelist=(Link<Elem>*)ptr;
}

//插入函数。此程序并没有用到次函数。
template <class Elem>
bool LList<Elem>::insert(const people& T)
{
 fence->next=new Link<Elem>(T,fence->next);//通过调用构造函数的初始化。
 if(tail==fence)
 {
  tail=fence->next;
  tail->next=head->next;
 }
 return true;
}
//从链表的尾插入。
template <class Elem>
bool LList<Elem>::append(const people& T)
{
 tail=tail->next=new Link<Elem>(T,head->next);//通过调用构造函数的初始化。
 return true;
}
template <class Elem>
bool LList<Elem>::remove(Elem& it)
{
   if(tail==head)
    return false;
   if(fence->next==NULL)
   {
    it=fence->element.pass;
    cout<<fence->element.NO<<"-- ";
    return true;
   }
   it=fence->next->element.pass;
   cout<<fence->next->element.NO<<"-- ";
   Link<Elem>* temp=fence->next;
   fence->next=temp->next;
   if(temp==tail)
   {
    tail=fence;//当是尾接点的时候要把他的尾指针指向标记指针
   
   }
   delete temp;
   return true;
}
//找下一个接点。
template <class Elem>
void LList<Elem>::prev()
{
   if(fence->next!=head)
    fence=fence->next;
   else
   {
    fence->next=head->next;
    fence=fence->next;
   }
       
 
}
//程序的主题//
template <class Elem>
void LList<Elem>::getOut(int &it,int& sum)
{
 int sign,n=1;
 fence=tail;//因为是从报到数的上一个人开始找到的删除点。所以要记得从head的上一个接点tail开始。
 cout<<"Enter you want to first get out:";
 cin>>sign;//报数值。
 while(sum>0)
 {
  if(sign>sum&&sign>1)   //为避免多次的循环找数通过取模可以节省时间。
   sign=sign%sum;

  if(sign==n||sum==1)
  {
    remove(it);
   sign=it; 
   sum--;
   n=0;//重新做标记从下一个人1开始。
  }
  else
     prev();//找下个接点。
  n++;
 }

 
}
       
int main()
{
 LList<int> A;
 struct people T;
 int item,it,sum;
 cout<<"Enter you want to people:";
 cin>>sum;
 for(int i=1;i<=sum;i++)
 {
  cout<<"enter the--"<<i<<"--pass:";
  cin>>item;
  T.NO=i;
  T.pass=item;
  A.append(T);//我这里是从尾插入的。
  cout<<endl;
 }
 A.getOut(it,sum);
 return 0;
}
 这是我学习数据结构和算法写的程序.我平时还可以看看自己写的程序.到以后自己有进步了.我在来看看自己的程序

是否是正确.合理的.
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值