循环链表解决约瑟夫斯问题
问题描述:设有n个人围坐成一个圆圈,按一定指向方向,从第s个人开始报数,数到m的人出列,然后从下一个人重新报数,数到m的人又出列,…,直到n个人全部出列为止。
输入:n m s,按次序输出得到的n个人的顺序表。
#include<iostream>
using namespace std;
typedef int datetype;
typedef struct node//构建链表节点
{
datetype data;
struct node* next;
}ListNode,*LinkList;//节点与表头指针
void CreateCircleLinkList(LinkList &rear,int n)//创建链表
{
ListNode *p,*pre;
p = NULL;
rear=pre= NULL;
for (int i = 0; i < n; i++)
{
p = new ListNode;
p->data = i + 1;
if (rear == NULL) rear = p;
if (pre != NULL) pre-> next= p;
pre = p;
}
p->next = rear;//循环链表的构建
pre = rear;//pre 指向链首节点
rear=p;//rear 指向链尾节点
}
void josephus(LinkList &rear,int m,int s)//约瑟夫斯 问题
{
ListNode *p;
for(int i=1;i<s;i++)//移到s-1个节点,从第s个人开始报数
{
rear=rear->next;
}
while(rear->next!=rear)//当循环链表不为一个节点
{
for(int i=1;i<m;i++)//移动m-1个人后再将第m个出列
{
rear=rear->next;
}
p=rear->next;
cout<<p->data<<" ";
rear->next=p->next;//将报到m的人出列
delete p;
}
cout << rear->data;
}
int main()
{
LinkList rear;
int n,m,s;
cin>>n>>m>>s;
cout << endl;
CreateCircleLinkList(rear,n);
josephus(rear,m,s);
}