约瑟夫问题C++代码实现:循环链表模拟退圈过程
该程序实现了约瑟夫退圈问题,使用循环链表模拟出圈过程。具体功能需求如下:
-
初始化链表头:
- 函数名:startset
- 输入参数:node*& m(链表头指针)
- 功能:创建一个循环链表的头节点,将其指针赋给m,并使其next指向自己。
-
建立循环链表(尾插法):
- 函数名:setlist
- 输入参数:int x(循环链表的长度)
- 功能:根据输入的循环链表长度x,创建一个循环链表,并将其尾节点的next指向头节点。
-
核心环节:
- 函数名:runlist
- 功能:实现约瑟夫退圈问题的核心逻辑。
- 输入参数:
- int n(总人数)
- int m(报数的最大值)
- int startId(开始报数的序号)
- 输出:依次出列人员的编号,最后剩下的人员编号。
- 功能流程:
- 初始化链表头。
- 输入总人数、报数的最大值和开始报数的序号。
- 创建循环链表。
- 移动节点到开始的那个数。
- 当圈不为1个人时,循环出圈:
- 当报数与m相等时,输出当前节点的编号,删除该节点,移动节点到下一个节点。
- 当报数不满m时,继续循环,移动节点到下一个节点。
- 输出最后剩下的人员编号。
-
主函数:
- 创建List对象。
- 调用runlist函数实现约瑟夫退圈问题的逻辑。
- 返回0。
#include<iostream>
using namespace std;
class List {
public:
//链表结构体
struct node {
int id;
node* next;
};
int m, startId, n;//m报数的最大值,n总人数,startId开始序号。
node* p, * r;
//构造函数:
List()
{
p = NULL;
}
//析构函数:
~List() {};
//初始化链表头:
void startset(node*& m)
{
m = new node;
m->next = m;
}
//建立循环链表(尾插法):
void setlist(int x)
{
node* q;
r = p;
p->id = 1;
for (int i = 2; i <= x; i++)
{
q = new node;
q->id = i;
r->next = q;
r = q;
}
r->next = p;//尾指针指向头节点。
}
//核心环节:
void runlist()
{
int i = 1;
startset(p);//初始化链表头。
cout << '请输入总人数:';
cin >> n;
cout << '请输入报数最大值:';
cin >> m;
cout << '请输入报数开始时的序号:';
cin >> startId;
system('pause');
cout << '依次出列人员的编号:\n';
setlist(n);//创建循环单列表。
//移动节点,到开始的那个数:
while (--startId)
{
p = p->next;
r = r->next;
}
//当圈不为1个人时,循环出圈:
if (p->next != p)
{
do {
if (i == m)//报数与m相等时。
{
i = 1;
cout << p->id << '号\n';
r->next = p->next;
delete(p);//删除结点。
p = r->next;
}
else//报数不满m时,继续循环。
{
r = r->next;
p = p->next;
++i;
}
} while (p->next != p);
}
//到最后剩下的人:
cout << '最后一位是:' << p->id << '号' << endl;
}
};
int main()
{
List list;
list.runlist();
return 0;
}
原文地址: https://www.cveoy.top/t/topic/qvPl 著作权归作者所有。请勿转载和采集!