问题:
编号为1,2,····n的n个人按顺时针做成一圈,一开始任选一个正整数作为报数的上限值m,从第一个人开始按顺时针方向自1开始顺时针报数,报到m时停止,这个人出列。从他在顺时针方向上的下一个人开始重新报数,如此下去,直至所有人出列。
下面是用STL中的list
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
int main()
{
int i, m = 6,n=20;
list<int> ilist;
//下面是用链表解决约瑟夫环问题
for (i = 1; i <= 20; i++)
ilist.push_back(i);
cout << "size= " << ilist.size() << endl;
list<int> ::iterator ite;
for (ite = ilist.begin(); ite != ilist.end(); ++ite)
cout << *ite << ' ';
cout << endl;
//m %= n;这是错误的
list<int>::iterator pit= ilist.begin();
while (!ilist.empty())
{
int i = 1;
for (; i < m; i++)
if (++pit == ilist.end())
pit = ilist.begin();
printf("%d ", *pit);
if((pit=ilist.erase())==ilist.end())
pit = ilist.begin();
//cout << *(pit)<<endl;
}
system("pause");
}
//用自己的循环链表解决
#include < iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <climits>
using namespace std;
struct node {
int data;
node* next;
node() { data = 0; next = nullptr; }
node(int x) { data = x; next = nullptr; }
};
//下面是约瑟夫问题(循环链表的操作)
node* node_creat(int n)
{
node* pRet = nullptr;
if (n != 0)
{
int n_idx = 1;
node* p_node = nullptr;
p_node=new node[n];
if (NULL==p_node )
{
return nullptr;
}
pRet=p_node;
while (n_idx < n)
{
p_node->data = n_idx;
p_node->next = p_node + 1;
p_node = p_node->next;
n_idx++;
}
p_node->data = n;
p_node->next = pRet;
}
return pRet;
}
void Josephus()
{
node* pList = NULL, *pIter = NULL;
int n = 20, m = 6;
pList = node_creat(n);
pIter = pList;
m %= n;
while (pIter != pIter->next)
{
int i = 1;
for (; i < m - 1; i++)
{
pIter = pIter->next;
}
//输出第m个节点
printf("%d ", pIter->next->data);
pIter->next = pIter->next->next;
pIter = pIter->next;
}
printf("%d\n", pIter->data);
delete []pList;//不要忘记释放内存
}
int main() {
Josephus();
}