约瑟夫循环队列C代码附带详细注释
时间: 2024-10-21 11:12:02 浏览: 87
约瑟夫循环队列(Josephus Problem)是这样一个问题:将一群人数定为N,每个人按顺序报数,报到M的那个人出列,然后从下一个开始再次报数,直到只剩下一个人为止。下面是一个包含详细注释的C语言实现:
```c
#include <stdio.h>
#include <stdlib.h>
// 定义约瑟夫环形队列的数据结构
typedef struct {
int *arr; // 存储元素的数组
int size; // 队列总大小
int front; // 队头位置
int count; // 队列中实际元素个数
} josephus_queue;
// 初始化约瑟夫环形队列,分配大小为size的空间
void init_josephus(josephus_queue *jq, int size, int step) {
jq->size = size;
jq->front = 0;
jq->count = 0;
jq->arr = (int*)malloc(size * sizeof(int)); // 分配内存
}
// 将元素value加入队列,遵循约瑟夫环规则
void enqueue(josephus_queue *jq, int value) {
jq->arr[jq->front] = value; // 插入元素
jq->front = (jq->front + 1) % jq->size; // 更新队头位置,遵循循环模式
jq->count++; // 队列元素计数加一
}
// 从队列中移除并返回第step个元素(遵循约瑟夫环规则)
int dequeue(josephus_queue *jq) {
if (jq->count == 0) { // 如果队列为空,返回-1
return -1;
}
int result = jq->arr[jq->front]; // 保存并移除队头元素
jq->arr[jq->front] = 0; // 清空队头位置
jq->front = (jq->front + step - 1) % jq->size; // 根据step更新队头位置
jq->count--; // 减少队列元素计数
return result;
}
// 判断是否所有元素都已经被移除(游戏结束)
int is_game_over(const josephus_queue *jq) {
return jq->count == 1; // 只剩下一个元素说明游戏结束
}
int main() {
josephus_queue jq;
int step, n, i;
printf("请输入报数步长 (k): ");
scanf("%d", &step);
printf("请输入初始人数: ");
scanf("%d", &n);
init_josephus(&jq, n + 1, step); // 由于循环,需要加1作为队列大小
for (i = 1; i <= n; i++) {
enqueue(&jq, i); // 从1开始报数
}
while (!is_game_over(&jq)) {
printf("被淘汰者: %d\n", dequeue(&jq)); // 输出淘汰者
}
free(jq.arr); // 游戏结束后释放内存
return 0;
}
```
在这个代码中,我们首先定义了一个约瑟夫环队列结构,然后分别实现了初始化、入队、出队和检查游戏是否结束的功能。`main()`函数中,用户输入步长和初始人数,然后执行游戏过程。
阅读全文