C语言n个人围成一圈,从第1个人开始顺序报号1、2、....k。凡报到k者推出圈子。找出最后留在圈子中的人原来的序号。本题要求用链表实现
时间: 2023-11-23 21:30:00 浏览: 71
c代码-自动报号简易
好的,这是一道经典的约瑟夫环问题,可以使用循环链表来实现。
首先,我们需要定义一个链表结构体,用来表示每个人:
```c
typedef struct node {
int num;
struct node *next;
} Node;
```
其中,num表示该人的编号,next表示指向下一个人的指针。接下来,我们需要先构建一个循环链表,将所有人的编号依次添加到链表中:
```c
int n, k; // n表示总人数,k表示报数为k的人出圈
Node *head, *tail;
void create_list() {
head = tail = (Node*)malloc(sizeof(Node)); // 创建头结点
head->num = 1;
for (int i = 2; i <= n; i++) {
Node *p = (Node*)malloc(sizeof(Node));
p->num = i;
tail->next = p;
tail = p;
}
tail->next = head; // 将尾结点指向头结点,形成循环链表
}
```
接下来,我们需要对链表进行遍历,每次找到第k个人,将其从链表中删除。直到链表中只剩下一个人为止:
```c
void josephus() {
Node *p = head, *q = tail;
while (p != q) { // 只剩下一个人时退出循环
for (int i = 1; i < k; i++) { // 找到第k个人
q = p;
p = p->next;
}
q->next = p->next; // 将该人从链表中删除
free(p);
p = q->next;
}
printf("%d", p->num); // 输出最后留下的人的编号
}
```
最后,完整代码如下:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int num;
struct node *next;
} Node;
int n, k;
Node *head, *tail;
void create_list() {
head = tail = (Node*)malloc(sizeof(Node)); // 创建头结点
head->num = 1;
for (int i = 2; i <= n; i++) {
Node *p = (Node*)malloc(sizeof(Node));
p->num = i;
tail->next = p;
tail = p;
}
tail->next = head; // 将尾结点指向头结点,形成循环链表
}
void josephus() {
Node *p = head, *q = tail;
while (p != q) { // 只剩下一个人时退出循环
for (int i = 1; i < k; i++) { // 找到第k个人
q = p;
p = p->next;
}
q->next = p->next; // 将该人从链表中删除
free(p);
p = q->next;
}
printf("%d", p->num); // 输出最后留下的人的编号
}
int main() {
scanf("%d%d", &n, &k);
create_list();
josephus();
return 0;
}
```
阅读全文