题目描述
N个人围成一圈,从第一个人开始报数,数到M的人出圈;再由下一个人开始报数,数到M的人出圈;……输出依次出圈的人的编号。N,M由键盘输入。
输入格式
一行,包含两个正整数N,M。1<=N,M<=100。
输出格式
先输出一个空行,再依次出圈的人的编号。每个编号后都有一个空格。
细节都在代码里
#include <stdio.h>
#include <stdlib.h>
typedef struct LNode
{
int data;
LNode *next;
} LNode, *LinkedList;
void InitList(LinkedList &L, int num)
{
//初始化一个链表头,也就是头节点
L = (LinkedList)malloc(sizeof(LNode));
L->next = nullptr;
//尾插法创建新链表
//用p创建节点,q保存上一新节点
LNode *p;
LNode *q = L;
for (int i = 1; i <= num; i++)
{
p = (LNode *)malloc(sizeof(LNode));
p->data = i;
p->next = nullptr;
q->next = p;
q = p;
}
//循环链表,将尾指针指向首元节点
p->next = L->next;
}
void Josephus(LinkedList &L, int count)
{
//保存当前节点cur和上一节点pre
LNode *cur = L->next;
LNode *pre = cur->next;
while (pre != cur)
{
for (int i = 0; i < count - 1; i++)
{
pre = cur;
cur = cur->next;
}
pre->next = cur->next;
LNode *q = cur;
printf("%d ", q->data);
cur = cur->next;
free(q);
}
printf("%d", cur->data);
}
int main()
{
int m, n;
scanf("%d %d", &n, &m);
LinkedList L;
printf("\n");
InitList(L, n);
Josephus(L, m);
}
这里说一下为什么pre初值为cur->next
。因为当链表中只有一个元素时,cur的上一个元素也就是它本身,所以cur->next
也就是cur。而链表中不止一个元素时,pre在遍历中可以通过pre=cur
来更新,从而不会影响后续的判断。