题目:
已知有n个人(编号分别为1,2,3,...,n分别表示)围坐在一张圆桌周围。编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。
解析:
根据题意,可以建立一个循环链表来完成出列情况,即建立一个具有n个链结点且无头结点的循环链表;将圆桌周围的每一个人对应着所建立的链表中的一个链结点,当某个人出列则意味着删除该结点。通过不断地删除链表中的链结点,直到链表中只剩下一个链结点,则该链结点为最后一个人出列。
#include<iostream>
#include<malloc.h>
using namespace std;
typedef struct node
{
int data;//数据域
struct node *link;//指针域
}lnode,*linklist;
void josephus(int n,int m,int k)
{
linklist p,r,list = NULL;
int i;
for(i=1;i<=n;i++)
{
p = (linklist)malloc(sizeof(lnode));//申请一个新的链结点
p->data = i;//存放第i个链结点
if(list == NULL)
list = p;
else
r->link = p;
r = p;
}
p->link = list;//创建成一个循环链表
p = list;
for(i=1;i<k;i++)//p指向第1个链结点
{
r = p;
p = p->link;
}
while(p->link != p)
{
for(i=1;i<m;i++)//p指向第m个结点,r指向第m-1个结点
{
r = p;
p = p->link;
}
r->link = p->link;//删除第m个结点
cout<<p->data<<" ";//输出一个结点编号
free(p);//释放并删除结点的空间
p = r->link;//p指向新的报数点
}
cout<<endl<<"最后一个出列的是:"<<p->data<<endl;
}
int main()
{
int n,m,k;
cout<<"输入人数:";
cin>>n;
cout<<"输入数到的数:";
cin>>m;
cout<<"编号为:";
cin>>k;
josephus(n,m,k);
return 0;
}