用C代码实现
时间: 2024-02-09 17:10:44 浏览: 58
以下是使用单向循环链表实现约瑟夫问题的C代码:
```c
#include <stdio.h>
#include <stdlib.h>
// 定义单向循环链表结点结构体
typedef struct ListNode {
int val;
struct ListNode* next;
} ListNode;
// 约瑟夫问题求解函数
void josephu(int n, int m) {
// 构造循环链表
ListNode* head = (ListNode*)malloc(sizeof(ListNode));
head->val = 1;
head->next = NULL;
ListNode* p = head;
for (int i = 2; i <= n; i++) {
p->next = (ListNode*)malloc(sizeof(ListNode));
p->next->val = i;
p->next->next = NULL;
p = p->next;
}
p->next = head; // 将链表尾部连接到头部,形成循环链表
// 模拟约瑟夫问题的求解过程
p = head;
while (p->next != p) { // 当链表中只剩一个结点时停止
for (int i = 1; i < m; i++) {
p = p->next; // 找到要删除的结点的前一个结点
}
ListNode* del = p->next; // 要删除的结点
p->next = del->next; // 将要删除的结点从链表中删除
printf("%d ", del->val); // 输出删除的结点的值
free(del); // 释放被删除结点的内存空间
}
printf("%d\n", p->val); // 输出最后剩下的结点的值
free(p); // 释放最后剩下的结点的内存空间
}
int main() {
int n, m;
printf("请输入总人数n和报数m:");
scanf("%d%d", &n, &m);
josephu(n, m);
return 0;
}
```
在上述代码中,我们首先构造了一个包含1~n的单向循环链表,然后模拟了约瑟夫问题的求解过程。具体来说,我们用一个指针p来遍历链表,每次找到要删除的结点的前一个结点,并将要删除的结点从链表中删除,并输出其值。当链表中只剩一个结点时,即p->next==p时,算法结束,输出最后剩下的结点的值。我们在释放节点的内存空间时使用了C语言中的malloc和free函数。
阅读全文