C语言约瑟夫环用链表实现
时间: 2024-12-20 20:07:51 浏览: 15
好的,我很乐意为您介绍如何使用C语言中的链表来实现约瑟夫环问题。
约瑟夫环问题是一个经典的数学和计算机科学问题。问题描述如下:有n个人(编号1,2,...,n)围成一圈,从第一个人开始报数,报到m的人出列,然后从下一个人重新开始报数,报到m的人再出列,依此类推,直到所有人都出列。求最后出列的人的编号。
下面是一个使用C语言链表实现约瑟夫环的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
// 定义链表节点结构
typedef struct Node {
int data;
struct Node* next;
} Node;
// 创建循环链表
Node* createCircularList(int n) {
Node* head = NULL;
Node* prev = NULL;
for (int i = 1; i <= n; i++) {
Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = i;
if (head == NULL) {
head = newNode;
} else {
prev->next = newNode;
}
prev = newNode;
}
prev->next = head; // 形成循环
return head;
}
// 模拟约瑟夫环过程
int josephus(int n, int m) {
Node* head = createCircularList(n);
Node* prev = head;
// 找到最后一个节点
while (prev->next != head) {
prev = prev->next;
}
while (head->next != head) {
// 移动到要删除的节点的前一个节点
for (int i = 1; i < m; i++) {
prev = head;
head = head->next;
}
// 删除节点
printf("出列的人:%d\n", head->data);
prev->next = head->next;
free(head);
head = prev->next;
}
int lastPerson = head->data;
free(head);
return lastPerson;
}
int main() {
int n, m;
printf("请输入总人数n:");
scanf("%d", &n);
printf("请输入报数m:");
scanf("%d", &m);
int last = josephus(n, m);
printf("最后剩下的人是:%d\n", last);
return 0;
}
```
这段代码的主要步骤如下:
1. 定义一个链表节点结构 `Node`。
2. 创建一个包含 `n` 个节点的循环链表,每个节点代表一个人。
3. 实现 `josephus` 函数来模拟约瑟夫环过程:
- 使用两个指针 `head` 和 `prev` 来跟踪当前节点和前一个节点。
- 在每一步中,移动 `m-1` 次,然后删除当前节点。
- 重复这个过程直到只剩一个节点。
4. 在 `main` 函数中,读取输入并调用 `josephus` 函数。
这个实现的时间复杂度是 O(nm),空间复杂度是 O(n)。
阅读全文