#include<stdlib.h>
#include<string>
#include<iostream>
using namespace std;
#define ElemType string
typedef struct LNode
{
ElemType info;
struct LNode* next;
}LNode,* Listq;
//循环链表初始化 头针指Lq向最后一个数据
bool InitialList(Listq& Lq)
{
int length=0;
char lengthS[4];
LNode *p=new LNode;
if(!p) return false;
Lq=p;
Lq->next=Lq;
ElemType x;
cin>>x;
while(x!="0"){
p=new LNode;
if(!p) return false;
p->info=x;
p->next=Lq->next;
Lq->next=p;
Lq=p;
++length;
cin>>x;
}
itoa(length,lengthS,10); //int转化为string类型 itoa(int,char[], 进制)
Lq->next->info=lengthS; //头结点的数据单存放表长信息
return true;
}
bool OutputList(Listq Lq) //输出函数
{
LNode *p=Lq->next->next;
while(p!=Lq->next){
cout<<p->info<<" ";
p=p->next;
}
cout<<endl;
return true;
}
void DeleLNode(Listq& Lq,LNode* pre,LNode* pos) //删除节点信息
{
LNode *head,*del,*tmp;
char lengthS[4];
int length=atoi((Lq->next->info).c_str()); //string 类型转换成int型
head=Lq->next;
del=pos;
tmp=pre;
pre->next=pos->next;
delete(del);
--length;
while(tmp->next!=head) //重新确定Lq的位置 因为删除的元素可能是Lq原来指向的
tmp=tmp->next;
Lq=tmp;
itoa(length,lengthS,10); //int 化string
Lq->next->info=lengthS; //改变长度
}
void Josephus(Listq Lq, int m) //约瑟夫函数 m为间隔数
{
int i,j,num;
num=atoi((Lq->next->info).c_str());
LNode* pre=Lq->next; //设计前驱指针用来删除
LNode* pos=Lq->next->next; //指向第一个数据元素
LNode* del=NULL;
for(i=0;i<num-1;++i) //一共删除n-1个
{
for(j=0;j<m-1;++j) //控制指针移动
{
pre=pre->next;
pos=pos->next;
while(pos==Lq->next) //头结点不能算在里面 此题不用头结点会简单很多
{
pre=pre->next;
pos=pos->next;
}
}
del=pos;
pos=pos->next; //指向下一人
DeleLNode(Lq,pre,del); //删
while(pos==Lq->next) //如果下一人是头结点 pre和pos一定要同时后移 如果pos不指向头结点 则pre不必后移 切记!!!!
{
pos=pos->next;
pre=pre->next;
}
OutputList(Lq);
}
}
void DeleList(Listq& Lq) //这函数没用
{
LNode *del,*p;
p=Lq->next;
while(p!=Lq)
{
del=p;
p=p->next;
delete(del);
}
delete(p);
}
int main()
{
Listq Lq;
InitialList(Lq);
OutputList(Lq);
Josephus(Lq,3);
return 0;
}