实验题目:约瑟夫环问题:设编号为1,2,3,……,n的n(n>0)个人按顺时针方向围坐一圈,m为任意一个正整数。从第一个人开始顺时针方向自1起顺序报数,报到m时停止并且报m的人出列,再从他的下一个人开始重新从1报数,报到m时停止并且报m的人出列。如此下去,直到所有人全部出列为止。要求设计一个程序模拟此过程,对任意给定的m和n,求出出列编号序列。
#include<iostream>
#define MAXSIZE 50
using namespace std;
typedef int Elemtype;
// 定义顺序表结构体
typedef struct
{
Elemtype data[MAXSIZE];
int length;
}Sqlist;
//另一种结构体类型名方式*Sqlist
//typedef struct
//{
// Elemtype data[MAXSIZE];
// int length;
//}*Sqlist;
//创建顺序表思想:直接把有几个人复制到顺序表中,没有书上那种的原因是书上是用的数组
void CreateList(Sqlist *& s)//另一种结构体时void CreatList(Sqlist s)
{
int n;
cout << "输入共有几个人" << endl;
cin >> n;
cout << " 最开始的编号为:" << endl;
for (int i = 0; i < n; i++)
{
s->data[i] = i + 1;
cout << s->data[i] << " ";
s->length = n;
}
cout << endl;
}
//初始化线性表
void InitList(Sqlist *& L)//另一种结构体时void InitList(Sqlist L)
{
L = (Sqlist*)malloc(sizeof(Sqlist));
L->length = 0;
}
// 实现约瑟夫环的算法:1.(t+m-1)%s->length, 这个s->length表示的是每次出列后参数顺序表的长度都会变化,通过%来实现环的意思跟环队形有点类似
//2.每次出列一个后,所有后面的数据向前一位顶替原来出列的数,形成一个新的表
//3.一共循环s->length次
void Joseph(Sqlist * s,int m)
{
int t=0;
int i,j;
cout << "出列序列" <<endl;
for (i = s->length; i >= 1; i--)
{
t = (t + m - 1) % i;//关键
cout << s->data[t] << " ";
for ( j = t + 1; j <= i - 1; j++)//关键
{
s->data[j - 1] = s->data[j];
}
}
cout << endl;
}
//实现约瑟夫环的算法:1.(t+m-1)%s->length, 这个s->length表示的是每次出列后参数顺序表的长度都会变化,通过%来实现环的意思跟环队形有点类似
//2.每次出列一个后,所有后面的数据向前一位顶替原来出列的数,形成一个新的表
//3.一共循环s->length次
//void Joseph(Sqlist* s, int m)//另一种结构体时(Sqlist L)
//{
// int t = 0;
// cout << "出列序列" << endl;
// for (s->length; s->length>= 1; s->length--)
// {
// t = (t + m - 1) % s->length;//关键
// cout << s->data[t] << " ";
//
// for (int j = t + 1; j <= s->length - 1; j++)//关键
// {
// s->data[j - 1] = s->data[j];
// }
// }
// cout << endl;
//}
int main()
{
Sqlist *L;//另一种结构体时Sqlist L;
int m;
InitList(L);
CreateList(L);
cout << "想要报的m数:" << endl;
cin >> m;
Joseph(L, m);
return 0;
}