循环链表解决约瑟夫斯问题


循环链表解决约瑟夫斯问题

问题描述:设有n个人围坐成一个圆圈,按一定指向方向,从第s个人开始报数,数到m的人出列,然后从下一个人重新报数,数到m的人又出列,…,直到n个人全部出列为止。
输入:n m s,按次序输出得到的n个人的顺序表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#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);
}

Author: cyy
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source cyy !
 Previous
算法 算法
@TOC 1.链表篇反转链表难度:easy 考察次数:189 传送门 题目描述输入一个链表,反转链表后,输出新链表的表头。 思路:创建三个指针,一个表示前一个结点pre,一个表示当前节点cur,一个表示后一个节点next。循环next=cu
2021-10-16 cyy
Next 
八皇后问题 八皇后问题
八皇后问题(链接) 努比亚和苏丹没有子女,所以他要从一些有集成资格的继承者中挑选一个出来继承王位。他希望这个继承者足够聪明,所以他准备了一个西洋棋盘,上面的每个格子中均有一个 $1-99$ 的数字。他又准备了 $8$ 个皇后棋子。
2021-10-15 cyy
  TOC