约瑟夫环实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一.需求分析
1.约瑟夫环(Joseph)问题的一种描述是:编号为1,2……,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。
2.演示程序以用户和计算机的对话方式执行,即在计算机终端上显示“提示信息”之后,有用户在键盘上输入演示程序中规定的运算命令,相应的输入数据和运算结果显示在其后。
3.程序执行的命令包括:
1)输入初始密码和人数2)输入所有人的密码3)显示输入的所有人的编号及相应的密码4)输出出列密码及编号5)结束
4.测试数据
(1)m=20, n=7, 7个人的密码依次为3,1,7,2,4,8,4
(2)m=20,n=1
(3)m=20,n=0
前面一组为常规数据,后面两组为边缘数据
二、概要设计
为实现上述功能,应以有序单向循环链表表示约瑟夫环。为此,需要有一个抽象数据类型。该抽象数据类型的定义为:
ADT LinkList
{
数据对象:D={ ai | ai ∈termset,i=1,2,……n,n>=0},
termset中每个元素包含编号,密码,和一个指向下一节点的指针数据关系:R1={
基本操作:
LinkList EvaluList(int n);//对单向循环链表进行尾插入赋值
int size(LinkList L);//求链表的节点个数
Status ScanList(LinkList L);//遍历单向循环链表
Status Joseph(LinkList &L,int m);//约瑟夫环的实现
}
此抽象数据类型中的一些常量如下:#define TRUE 1
#define FALSE 0
#define OK 1
typedef int Status;
typedef double ElemType;
单向循环链表中节点的定义如下所示:typedef struct LNode
{
int number;
int data;
struct LNode *next;
}LNode, *LinkList;
三、详细设计
#include
using namespace std;
#define TRUE 1
#define FALSE 0
#define OK 1
typedef int Status;
typedef double ElemType;
//-----------------------------------
//定义单向循环链表
typedef struct LNode
{
int number;
int data;
struct LNode *next;
}LNode, *LinkList;
//-----------------------------------
LinkList EvaluList(int n);//对单向循环链表进行尾插入赋值
int size(LinkList L);//求链表的节点个数
Status ScanList(LinkList L);//遍历单向循环链表
Status Joseph(LinkList &L,int m);//约瑟夫环的实现
//-------------------------------------------------
void main()
{
int m,n;
cout<<"请输入初始密码(正整数)和人数"< cin>>m>>n; cout< LinkList L=EvaluList(n); cout< ScanList(L); cout< Joseph(L,m); } //---------对单向循环链表进行尾插入赋值---------------- LinkList EvaluList(int n) { if(n==0) return NULL; int key; cout<<"输入第1个人的密码"; cin>>key; LinkList L=new LNode; L->data=key; L->number=1; L->next=L; for(int i=2;i<=n;i++) { LinkList p=new LNode; int key; cout<<"输入第"< cin>>key; p->data=key; p->number=i; p->next=L->next; L->next=p; L=L->next; } cout< L=L->next; return L; } //---------------求链表的节点个数------------------- int size(LinkList L) { if(L==NULL) return 0; int i=1; LinkList p=L->next; while(p!=L) { i++; p=p->next; } return i; } //---------------遍历单向循环链表--------------------