约瑟夫环问题是:编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码。一开始任选一个正整数作为报数上限值m,从第一个人开始顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。
#include
using namespace std;
#include
#include
#define LIST_INIT_SIZE 100
#define LISTINCREMENT 10
#define NULL 0
#define OK 1
typedef struct LNode
{
int num;
int data;
struct LNode* next;
}LNode, * LinkList;
LinkList p, q;
int i, j, m;
void CreateList_L(LinkList& L, int n)
{ //逆位序输入n 个元素的值,建立一个带头结点的循环单链表L
L = (LinkList)malloc(sizeof(LNode));//创建新结点
L->next = NULL;
cout << "请输入每个人分配的密码:" << endl;
q = L;
for (i = 1; i <= n; ++i)
{
p = (LinkList)malloc(sizeof(LNode));
p->num = i;
cout << endl;
cin >> p->data;
q->next = p;
p->next = L->next;
q = p;
}
}//CreateList_L
void ListOut_L(LinkList& L, int n)//删除元素,n为线性表元素个数,
{
cout << "请输入起始密码:" << endl;
cin >> i;
cout << "出列的顺序依次为:" << endl;
q = L; p = L->next;
for (m = 1; m <= n; m++)//建立一个循环,实现删除n个元素
{
for (j = 1; j != i; j++)
{
p = p->next;
q = q->next;
}
cout << p->num << ",";
i = p->data;
q->next = p;
p = q;
p->next = q->next->next;
p = p->next;
q->next = p;
}
}//ListOut_L
void getout(LinkList& L, int n)//输出线性表函数
{
p = L; i = 1;
cout << endl << "输出每个人的编号和密码:" << endl << "L=(";
for (p = p->next; i <= n; p = p->next, i++)
cout << "(" << p->num << "," << p->data << "),";
cout << "\b" << ")" << endl;
}//getout
int main()
{
LinkList L;
int n;
cout << "请输入数:" << endl;
cin >> n;
CreateList_L(L, n);
getout(L, n);
ListOut_L(L, n);
system("pause");
}
约瑟夫环问题不一定要用链表实现,我曾在 C
语言网上写过一篇类似题目的题解,你可以看看: