问题描述:
设编号为1,2,、、、,n(n>0)的人按顺时针方向围坐一圈,每人持有一个正整数密码。开始时任意给出一个报数上限值m,从第一个人开始沿顺时针方向自1起顺序报数,报到m时停止报数,报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人起重新自1起顺序报数;如此下去,直到所有人全部出列为止。
基本要求:
<1>初始上限值m和测试数据在程序中确定;
<2>用带头结点的单循环链表作数据元素的存储结构;
<3>把带头结点的单循环链表作为抽象数据类型设计;测试数据:n=7;七个人的密码:3,1,7,2,4,8,4.初始报数上限m=20.
本人编的源代码:
#include <iostream.h>
#include <malloc.h>
#define NULL 0
typedef struct Node
{
int code,num;
struct Node *next;
}LNode,*LinkList;
LinkList Creat_LinkList(int personnum) //在单链表的尾部插人结点建立单链表,并完成
{ 初始化,需要参数传递,返回头点;
LinkList s,r,L;
L=(LinkList)malloc(sizeof(LNode)); //建立头结点L;
L->next=NULL;
r=L;
for(int i=1;i<=personnum;i++) //尾插法建立单链表并进行初始化;
{
s=(LinkList)malloc(sizeof(LNode));
cout<<“Person “<<i<<” code is: “;
cin>>s->code;
s->num=i;
if(L->next==NULL)
L->next=s;
else
r->next=s;
r=s;
}
r->next=L->next; //让单链表循环起来;
return L; //返回头结点;
}
void Joseph(LinkList head,int key,int personnum) //约瑟夫问题的实现;
{
LinkList p,s;
while(personnum>0)
{
p=head; //p为每次循环开始的位置;
for(int i=1;i<=key;i++) //具体的一次循环,为了找到出列的人;
{
s=p;
p=p->next;
}
key=p->code;
cout<<p->num<<” “; //输出出列人的编号;
s->next=p->next; //删除p所指的结点;
head=s; //确立下一次循环开始的位置;
free(p); //释放出列人所在结点的空间;
personnum–; //结点数减一;
}
}
void main()
{
LinkList Llist;
int m,n;
cout<<“Please input the limited number : “;
cin>>m;
cout<<“Please input how many persons : “;
cin>>n;
cout<<“Please input everyone’s code : “<<endl;
Llist=Creat_LinkList(n);
cout<<“Person out sequence:”<<endl;
Joseph(Llist,m,n);
cout<<endl;
}