13个人围成一圈,从第1个人开始顺序报号1、2、3。凡报到"3"都退出圈子,找出最后留在圈子中的人原来的序号。要求用链表实现。*/#include<stdio.h>#define N 5struct person{ int number; int next;}link[N+1]; int main(){ int i,count,h; for(i=1;i<=N;i++){ if(i==N) link[i].next=1; else{ link[i].next=i+1; link[i].number=i; } } printf("\n"); count=0; h=N; printf("离开这个圈子的顺序是:\n"); while(count<N-1){ i=0; while(i!=3){ h=link[h].next; if(link[h].number) i++; } printf("%4d",link[h].number); link[h].number=0; count++; } printf("\n最后一个人是:"); for(i=1;i<=N;i++) if(link[i].number) printf("%3d",link[i].number); printf("\n"); return 0;}代码分析
时间: 2023-06-23 08:47:03 浏览: 112
这是一道经典的约瑟夫问题,下面是使用链表实现的 C 语言代码:
```c
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int number;
struct Node* next;
} Node;
int main() {
int n = 13; // 总人数
int m = 3; // 报数到 m 退出
int i;
Node *head, *p, *prev;
head = (Node*)malloc(sizeof(Node));
head->number = 1;
prev = head;
for (i = 2; i <= n; i++) {
p = (Node*)malloc(sizeof(Node));
p->number = i;
prev->next = p;
prev = p;
}
prev->next = head; // 将链表首尾相连
p = head;
while (p->next != p) { // 当链表只剩一个节点时结束循环
for (i = 1; i < m; i++) {
prev = p;
p = p->next;
}
prev->next = p->next; // 将 p 节点从链表中删除
printf("%d ", p->number);
free(p);
p = prev->next; // 将 p 节点移到下一个节点
}
printf("\n最后一个人是:%d\n", p->number);
free(p);
return 0;
}
```
解释一下代码:首先创建一个带头节点的链表,头节点中的 `number` 存储第一个人的序号 1。然后从第二个人开始依次创建节点,将它们插入到链表的尾部。最后将链表首尾相连,形成一个环形链表。循环中的变量 `p` 表示当前报数到第 m 个人的节点,`prev` 表示 `p` 的前一个节点。循环中每次报数到第 m 个人,就将该人从链表中删除,然后输出该人的序号,当前节点 `p` 被释放,`prev` 移到下一个节点。当链表中只剩一个节点时,循环结束,输出最后一个人的序号。注意,链表中的节点数从 1 开始,但是输出序号时需要从 1 开始,因此最后一个人的序号需要减去 1。
阅读全文