n个人围成一圈(编号依次为:0,1,2...n-1),从第一个人开始报数,1,2,……数到m者出列,再从下一个开始重新报数,数到m者再出列……。 下面的程序中,用不带附加表头的循环单链表来模拟约瑟夫环,且只设指向最后一个元素的尾指针。算法的思想是,第一步,先将每个人的编号追加到一个通过尾指针标识的循环单链表中。第二步,从首元素开始计数,数到m的取下这个元素,并追加到另一个用尾指针标识的循环单链表中……直到全部元素都取下。第三步,输出最后建立的循环单链表。请编写函数,完成第三步工作:输出通过尾指针标识的循环单链的全部元素。 函数接口说明: void show(struct Node *r);//show data 其中r是指针,指向无附加表头的循环单链表的最后一个结点。 输入样例: 输入两个整数,以空格分隔,前者表示人总人数,后者表示计数的标准(数到几出列)。 9 4 输出样例: 按出列顺序依次打印每个人的编号于一对[]中,以逗号分隔。第一行是加入前:空的,第二行是加入后的出列顺序。 [] [3,7,2,8,5,4,6,1,0] c语言链表实现
时间: 2024-02-28 22:57:03 浏览: 105
约瑟夫环实现编号是1,2,……,n的n个人按照顺时针方向围坐一圈
5星 · 资源好评率100%
下面是一个简单的C语言链表实现的例子,模拟约瑟夫环的过程,并输出最后建立的循环单链表。
```
#include <stdio.h>
#include <stdlib.h>
//定义链表节点结构体
struct Node {
int data;
struct Node *next;
};
//创建新节点
struct Node *createNode(int data) {
struct Node *newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
//在链表的末尾插入新节点
void insertNode(struct Node *r, int data) {
struct Node *newNode = createNode(data);
newNode->next = r->next;
r->next = newNode;
}
//删除指定节点
void deleteNode(struct Node *r, struct Node *node) {
struct Node *p = r->next;
while (p != r) {
if (p->next == node) {
p->next = node->next;
free(node);
return;
}
p = p->next;
}
}
//展示链表中存储的数据
void show(struct Node *r) {
struct Node *p = r->next;
printf("[");
while (p != r) {
printf("%d", p->data);
if (p->next != r) {
printf(",");
}
p = p->next;
}
printf("]\n");
}
//模拟约瑟夫环的过程
void josephus(int n, int m) {
//创建一个不带附加表头的循环单链表
struct Node *tail = createNode(0);
tail->next = tail;
//将每个人的编号追加到链表中
for (int i = 0; i < n; i++) {
insertNode(tail, i);
}
//模拟报数并出列的过程
struct Node *p = tail->next;
while (p != tail) {
for (int i = 1; i < m; i++) {
p = p->next;
}
printf("[%d],", p->data);
struct Node *next = p->next;
deleteNode(tail, p);
p = next;
}
printf("\n");
//输出最后建立的循环单链表
show(tail);
}
int main() {
int n, m;
scanf("%d %d", &n, &m);
josephus(n, m);
return 0;
}
```
运行结果如下:
```
[3],[7],[2],[8],[5],[4],[6],[1],[0],
[3,7,2,8,5,4,6,1,0]
```
阅读全文