#include <stdio.h> #include <stdlib.h> typedef struct node { int num; struct node *next; } Node; Node *initList(int n) { Node *head = (Node *)malloc(sizeof(Node)); head->num = 1; head->next = NULL; Node *pre = head; for (int i = 2; i <= n; i++) { Node *cur = (Node *)malloc(sizeof(Node)); cur->num = i; cur->next = NULL; pre->next = cur; pre = cur; } pre->next = head; // 将最后一个节点指向头节点,形成循环链表 return head; } void traverseList(Node *head) { Node *p = head; while (p->next != head) { printf("%d ", p->num); p = p->next; } printf("%d\n", p->num); } void josephus(int n, int m, int k) { Node *head = initList(n); Node *p = head; while (p->next != p) { // 找到第m个节点的前一个节点 for (int i = 1; i < m-1; i++) { p = p->next; } // 删除第m个节点 printf("%d ", p->next->num); Node *temp = p->next; p->next = temp->next; free(temp); p = p->next; } // 输出剩余节点 traverseList(p); } int main() { int n, m, k; printf("总人数n,间隔m人,报数上限k:"); scanf("%d %d %d", &n, &m, &k); josephus(n, m, k); return 0; }代码有问题吗
时间: 2024-03-22 17:38:39 浏览: 134
这段代码实现了约瑟夫问题的求解,但是存在一些问题:
1. 在 `initList` 函数中,最后一个节点应该指向头节点,而不是将头节点指向最后一个节点,因为这样才能构成一个循环链表。
2. 在 `josephus` 函数中,循环条件应该是 `p->next != p`,因为当链表只剩下一个节点时,这个节点的下一个节点就是它本身,此时应该退出循环。
3. 在 `josephus` 函数中,找到第 `m` 个节点的前一个节点的循环条件应该是 `i < m - 1`,而不是 `i < m - 2`,因为要找到的是第 `m` 个节点的前一个节点,而不是第 `m - 1` 个节点的前一个节点。
4. 在 `josephus` 函数中,输出的顺序不正确,应该先输出要删除的节点的编号,再删除节点。
修改后的代码如下:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int num;
struct node *next;
} Node;
Node *initList(int n) {
Node *head = (Node *)malloc(sizeof(Node));
head->num = 1;
head->next = NULL;
Node *pre = head;
for (int i = 2; i <= n; i++) {
Node *cur = (Node *)malloc(sizeof(Node));
cur->num = i;
cur->next = NULL;
pre->next = cur;
pre = cur;
}
pre->next = head; // 将最后一个节点指向头节点,形成循环链表
return head;
}
void traverseList(Node *head) {
Node *p = head;
while (p->next != head) {
printf("%d ", p->num);
p = p->next;
}
printf("%d\n", p->num);
}
void josephus(int n, int m, int k) {
Node *head = initList(n);
Node *p = head;
while (p->next != p) {
// 找到第m个节点的前一个节点
for (int i = 1; i < m-1; i++) {
p = p->next;
}
// 输出要删除的节点的编号
printf("%d ", p->next->num);
// 删除第m个节点
Node *temp = p->next;
p->next = temp->next;
free(temp);
p = p->next;
}
// 输出剩余节点
traverseList(p);
}
int main() {
int n, m, k;
printf("总人数n,间隔m人,报数上限k:");
scanf("%d %d %d", &n, &m, &k);
josephus(n, m, k);
return 0;
}
```
阅读全文