- C++
约瑟夫问题 循环链表
- 2025-7-3 22:09:10 @
这个程序模拟了约瑟夫问题的过程。简单来说,约瑟夫问题是这样的:有n个人围成一圈,从第一个人开始报数,报到k的人出列,然后从出列的下一个人重新开始报数,直到所有人都出列。程序会输出出列的顺序和最后剩下的人。
程序的核心是使用循环链表来表示围成一圈的人。每个节点代表一个人,包含一个编号和一个指向下一个人的指针。当一个人出列时,我们只需要调整指针,将他从链表中移除即可。
运行程序后,你可以输入总人数n和报数间隔k,程序会模拟整个淘汰过程并输出结果。这个程序适合中小学生理解链表结构和循环逻辑。
#include <iostream>
using namespace std;
// 定义链表节点结构
struct Node {
int data; // 节点存储的数据(人的编号)
Node* next; // 指向下一个节点的指针
// 构造函数,初始化节点
Node(int value) : data(value), next(nullptr) {}
};
// 创建循环链表
Node* createCircularList(int n) {
if (n <= 0) return nullptr;
// 创建第一个节点
Node* head = new Node(1);
Node* current = head;
// 创建剩余的n-1个节点,并连接成环
for (int i = 2; i <= n; ++i) {
current->next = new Node(i);
current = current->next;
}
// 最后一个节点指向头节点,形成环
current->next = head;
return head;
}
// 解决约瑟夫问题的函数
void josephusProblem(int n, int k) {
if (n <= 0 || k <= 0) {
cout << "参数必须为正整数!" << endl;
return;
}
// 创建循环链表
Node* head = createCircularList(n);
Node* prev = nullptr; // 当前节点的前一个节点
Node* current = head; // 当前节点,从第一个人开始
cout << "出列顺序:";
// 当链表中不止一个节点时,继续淘汰过程
while (current->next != current) {
// 找到第k个节点
for (int i = 1; i < k; ++i) {
prev = current;
current = current->next;
}
// 输出被淘汰的人的编号
cout << current->data << " ";
// 删除当前节点
prev->next = current->next; // 跳过当前节点
Node* temp = current;
current = current->next; // 移动到下一个节点
delete temp; // 释放内存
}
// 输出最后剩下的人的编号
cout << current->data << endl;
cout << "最后剩下的人是:" << current->data << endl;
// 释放最后一个节点的内存
delete current;
}
int main() {
int n, k;
cout << "欢迎来到约瑟夫环问题模拟程序!" << endl;
cout << "请输入总人数 n:";
cin >> n;
cout << "请输入报数间隔 k:";
cin >> k;
josephusProblem(n, k);
return 0;
}
0 条评论
目前还没有评论...