1.5 约瑟夫环是个经典的问题。有M个人围坐成一圈,编号依次从1开始递增,现从编号为1的人开始报数,报到N的人出列,然后再从下一人开始重新报数,报到N的人出列;重复这一过程,直至所有人出列。求出列次序。本题要求用循环单链表实现。提示:开始时将循环单链表的指针变量设为空,设计实现尾部添加一人函数Append,添加第1人时,将结点的指针域指向自己,后面新添加人员时,在循环单链表指针变量所指尾部后添加新结点,并始终将循环单链表指针变量指向新添加结点,对应M个人的循环单链表中有M个结点;报数时,报到指定数后输出对应结点里的人员编号,并将该结点从链表中删除。题目输入包括M、N两个正整数,题目要求按出队列顺序输出他们的编号。c语言代码
时间: 2024-03-12 07:50:32 浏览: 239
以下是用C语言实现约瑟夫环问题的代码。其中,使用循环单链表来模拟人围坐成一圈的情况,每个节点保存一个人的编号,使用指针来进行链表的操作。
```c
#include <stdio.h>
#include <stdlib.h>
// 定义循环单链表节点结构体
struct Node {
int num; // 编号
Node* next; // 指向下一个节点的指针
};
// 在链表末尾添加节点
void append(Node* &tail, int val) {
Node* newNode = new Node;
newNode->num = val;
if (tail == NULL) { // 链表为空
newNode->next = newNode;
tail = newNode;
} else {
newNode->next = tail->next;
tail->next = newNode;
tail = newNode;
}
}
int main() {
int M, N;
printf("请输入M和N的值:");
scanf("%d %d", &M, &N);
Node* tail = NULL; // 循环单链表的尾指针
for (int i = 1; i <= M; i++) {
append(tail, i); // 在链表末尾添加节点
}
Node* p = tail->next; // p指向链表的第一个节点
while (M > 0) { // 当链表不为空时
for (int i = 1; i < N; i++) { // 报数
p = p->next;
}
printf("%d ", p->num); // 输出出列的人员编号
Node* q = p; // 保存p的前一个节点
p = p->next; // p指向下一个节点
q->next = p; // 删除p节点
delete p;
M--;
}
return 0;
}
```
以上代码实现了约瑟夫环问题的功能,并按照出队列顺序输出了人员编号。
阅读全文