双链表_解决约瑟夫问题
#include<iostream>
using namespace std;
typedef int Node;
typedef struct DblNode
{
Node data;
DblNode *lLink,*rLink;
}DblNode;
class Dblist
{
DblNode *first;
public:
//==========构造函数==================
Dblist();
// ~Dblist();
//==========返回双链表长度============
int Length() const;
//==========判断双链表空否============
bool IsEmpty(){return first->rLink==first;}
//==========取附加头节点地址==========
DblNode *getHead()const {return first;}
//==========设置附加头节点地址=========
void setHead(DblNode *ptr){first=ptr;}
//==========在链表中沿后继方向寻找等于给定值X的节点
DblNode *Search(const Node &x);
//==========在链表中定位序号为i(≥0)的节点,d=0按前驱方向,d≠0按后继方向
DblNode *Locate(int i,int d);
//==========在第i个节点后插入一个包含有值x的新节点,d=0按前驱方向,d≠0按后继方向
bool Insert(int i,const Node &x,int d);
//==========删除第i个节点,x返回其值,d=0按前驱方向,d≠0按后继方向
bool Remove(int i,Node &x,int d);
//=========删除节点并返回其值=================
int Remove(DblNode *x);
//=======返回所有结点的值====================
void GetElement();
//=======返回下一结点====================
DblNode *Next(DblNode* node){node=node->rLink; return node;}
};
//==========类的实现部分=================
Dblist::Dblist()
{
first=new DblNode;
if(first==NULL){cerr<<"存储分配出错!"<<endl;exit(1);}
first->rLink=first->lLink=first;
}
/*Dblist::~Dblist()
{
}
*/
//==========返回双链表长度============
int Dblist::Length() const
{
DblNode *current=first->rLink; int count=0;
while(current!=first){current=current->rLink;count++;}
return count;
}
//==========在链表中沿后继方向寻找等于给定值X的节点
DblNode * Dblist::Search(const Node &x)
{
DblNode *current=first->rLink;
while(current!=first && current->data !=x)
current=current->rLink;
if(current!=first)return current;
else return NULL;
}
//==========在链表中定位序号为i(≥0)的节点,d=0按前驱方向,d≠0按后继方向
DblNode * Dblist::Locate(int i,int d)
{
if(first->rLink==first || i==0)return first;
DblNode *current;
if(d==0) current=first->lLink;
else current=first->rLink;
for(int j=1;j<i;j++)
{
if(current==first)break;
else if(d==0)current=current->lLink;
else current=current->rLink;
}
if(current !=first)return current;
else return NULL;
}
//==========在第i个节点后插入一个包含有值x的新节点,d=0按前驱方向,d≠0按后继方向
bool Dblist::Insert(int i,const Node &x,int d)
{
DblNode *current=Locate(i,d);
if(current==NULL)return false;
DblNode *newNode=new DblNode;
newNode->data=x;
newNode->lLink=NULL;
newNode->rLink=NULL;
if(newNode==NULL){cerr<<"存储分配失败!"<<endl;exit(1);}
if(d==0)
{
newNode->lLink=current->lLink;
current->lLink=newNode;
newNode->lLink->rLink=newNode;
newNode->rLink=current;
}else
{
newNode->rLink=current->rLink;
current->rLink=newNode;
newNode->rLink->lLink=newNode;
newNode->lLink=current;
}
return true;
}
//==========删除第i个节点,x返回其值,d=0按前驱方向,d≠0按后继方向
bool Dblist::Remove(int i,Node &x,int d)
{
DblNode *current=Locate(i,d);
if(current==NULL)return false;
current->rLink->lLink=current->lLink;
current->lLink->rLink=current->rLink;
x=current->data;delete current;
return true;
}
//==========删除节点x返回其值===============
int Dblist::Remove(DblNode *x)
{
DblNode *p=x->rLink;
p->rLink->lLink=p->lLink;
p->lLink->rLink=p->rLink;
int data=p->data;
delete p;
return data;
}
//=======返回所有结点==================
void Dblist::GetElement()
{
DblNode *current=first->rLink;
while(current->rLink!=first->rLink)
{
cout<<" "<<current->data ;
current=current->rLink ;
}
}
void main()
{
Dblist mylink;
cout<<"利用双向循环链表求解约瑟夫(Josephus)问题:"<<endl;
int i,j,k,n,m,d;
cout<<"输入人数 n:";cin>>n;
cout<<"输入第次数 m:";cin>>m;
cout<<"d=0按前驱方向,d≠0按后继方向:";cin>>d;
for(i=0;i<n;i++)
{
mylink.Insert(i,i+1,d);
}
cout<<"员工编号依次为:";
DblNode *node=mylink.Locate(1,d);
mylink.GetElement();
cout<<"删除次序依次为:\n";
for(i=1;i<n;i++)
{
for(int j=0;j<m;j++)
{
node=mylink.Next(node);
if(node==mylink.Locate(0,d)) node=mylink.Next(node);
}
if(node==mylink.Locate(0,d)->lLink) node=mylink.Next(node);
cout<<"删除第"<<mylink.Remove(node)<<"人\n";
}
cout<<"最后剩下的是:编号为"<<mylink.Locate(1,d)->data<<"的员工。\n";
}