问题描述:编号为1,2… n 的n 个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1 开始顺序报数,报到m 时停止报数,报m 的人出列,将他的密码作为新的m 值,从他的顺时针方向上的下一个开始重新从1 报数,如此下去,直至所有人全部出列为止,设计一个程序求出出列顺序。
基本功能要求:
1)利用单循环链表作为存储结构模拟此过程;
2)键盘输入总人数、各人密码、开始位置及初始报数上限值m ;
3)按照出列顺序输出各人的编号。
#include <iostream>
using namespace std;
typedef struct Node
{
int data;
int word; //密码
struct Node *next;
}LNode,*LinkList;
LinkList CreateCyList(int n);
void OutputCyList(LinkList l);
void Josephus(LinkList l,int m,int n);
int main(int argc, char const *argv[])
{
int m,n;
cout<<"请输入总人数:";
cin>>n;
LinkList h = CreateCyList(n);
//OutputCyList(h);
cout<<"请第一次输入报数的上限值:";
cin>>m;
Josephus(h,m,n);
return 0;
}
LinkList CreateCyList(int n)
{
LinkList head = NULL;
int i;
LNode *s,*r;
for (i=1; i<=n; i++)
{
s = new LNode;
s->data = i;
s->next = NULL;
if(head==NULL)
head = s;
else
r->next = s;
r = s;
cout<<"请请入第"<<i<<"个人的密码:";
cin>>r->word;
}
r->next = head;
return head;
}
void OutputCyList(LinkList l)
{
LNode *p;
p = l;
if(p==NULL)
{
cout<<"该链表为空表"<<endl;
return;
}
while(p->next!=l)
{
cout<<p->data<<" ";
p = p->next;
}
cout<<p->data<<endl;
}
void Josephus(LinkList l,int m,int n)
{
LNode *p = l,*q;
int j = 1;
cout<<"出队顺序为:";
for(int i=1;i<=n;i++)
{
j=1;
while(j<m)
{
q=p;
j++;
p = p->next;
}
m = p->word;
cout<<p->data<<" ";
q->next = p->next;
delete p;
p = q->next;
}
}