C++单链表实现约瑟夫环问题:算法解析与代码示例
C++单链表实现约瑟夫环问题:算法解析与代码示例
约瑟夫环问题是一个经典的算法问题,可以用循环链表(单链表的一种特殊形式)高效解决。本文将详细介绍如何使用C++的单链表实现约瑟夫环问题,并提供完整的代码示例和解释。
1. 问题描述
约瑟夫环问题可以描述如下:
- M个人围成一圈,按顺序编号为1到M。* 从第一个人开始报数,报到N的人出列。* 从出列者的下一个人开始重新报数,报到N的人再次出列。* 重复上述过程,直到所有人都出列。
要求输出出列人员的编号顺序。
2. 算法思路
使用单链表解决约瑟夫环问题的核心思想是:
- 创建一个包含M个节点的循环单链表,每个节点代表一个人,节点数据存储人员编号。2. 遍历链表,模拟报数过程,找到要出列的节点。3. 删除该节点,并将链表重新连接成环。4. 重复步骤2和3,直到链表为空。
3. 代码实现
以下是使用C++实现约瑟夫环问题的代码:cpp#include
// 定义链表节点结构体struct ListNode { int data; // 节点数据,存储人员编号 ListNode* next; // 指向下一个节点的指针 ListNode(int x) : data(x), next(NULL) {} // 构造函数};
// 创建包含M个节点的循环单链表ListNode* createList(int M) { ListNode* head = new ListNode(1); // 创建头节点 ListNode* cur = head; for (int i = 2; i <= M; i++) { // 创建剩余节点并连接 ListNode* newNode = new ListNode(i); cur->next = newNode; cur = newNode; } cur->next = head; // 尾节点指向头节点,形成循环链表 return head;}
// 模拟约瑟夫环游戏过程void josephus(ListNode* head, int N) { ListNode* cur = head; while (cur->next != cur) { // 当链表中还有多个节点时 for (int i = 1; i < N - 1; i++) { cur = cur->next; // 找到要删除节点的前一个节点 } ListNode* temp = cur->next; // 要删除的节点 cur->next = temp->next; // 删除节点,连接前后节点 cout << setw(4) << setfill(' ') << temp->data; // 输出出列人员编号 delete temp; // 释放删除节点内存 cur = cur->next; // 更新当前节点 } cout << setw(4) << setfill(' ') << cur->data << endl; // 输出最后一个出列人员编号 delete cur; // 释放最后一个节点内存}
// 进行多轮约瑟夫环游戏void playJosephusGame(int M, int* passwords, int numPasswords) { ListNode* head = createList(M); // 创建初始链表 for (int i = 0; i < numPasswords; i++) { josephus(head, passwords[i]); // 进行一轮游戏 }}
int main() { int M; cin >> M; // 输入游戏人数
int numPasswords; cin >> numPasswords; // 输入游戏轮数
int* passwords = new int[numPasswords]; for (int i = 0; i < numPasswords; i++) { cin >> passwords[i]; // 输入每轮游戏的报数密码 }
playJosephusGame(M, passwords, numPasswords); // 开始游戏
delete[] passwords; // 释放内存 return 0;}
4. 输入输出样例
输入:
10 33 5 2
输出:
3 6 9 2 7 1 8 5 10 4 4 6 5 2 9 1 3 7 8 10 2 5 8 1 7 4 10 6 3 9
5. 代码解释
createList(int M)函数:创建一个包含M个节点的循环单链表,表示初始的人员队列。2.josephus(ListNode* head, int N)函数:模拟一轮约瑟夫环游戏,根据报数密码N删除节点并输出出列人员编号。3.playJosephusGame(int M, int* passwords, int numPasswords)函数:根据输入的游戏轮数和每轮的报数密码,进行多轮约瑟夫环游戏。4.main()函数:读取输入数据,调用游戏函数,并释放内存。
6. 总结
使用C++单链表可以清晰地模拟约瑟夫环游戏的过程,代码易于理解和维护。通过学习本例,您可以更好地理解单链表的应用,并掌握解决类似循环问题的方法。
原文地址: https://www.cveoy.top/t/topic/Rqy 著作权归作者所有。请勿转载和采集!