资源描述
资料内容仅供您学习参考,如有不当或者侵权,请联系改正或者删除。
目录
第一章 需求分析 1
1.1课程设计目的 1
1.2课程设计要求 1
1.3课程设计目标与总体方案 1
1.4程序执行的命令 1
第二章 系统的功能 2
2.1系统功能说明 2
2.2 系统功能解析 2
第三章 系统的设计 3
3.1Josphu链表的实现 3
3.2循环链表 3
3.3 对程序的各个部分的详细介绍 3
3.3.1利用类定义构造成员函数以及成员 3
3.3.2 定义成员函数 4
3.3.3创立含有n个结点的单循环链表 5
3.3.4 Josephu操作 5
3.3.5主函数 6
3.4程序的流程 7
第四章 程序的运行结果图 8
4.1开始运行程序 8
4.2先键入参加游戏的人数及报数间隔 8
4.3按空格键运行程序 9
第五章 总结 10
致谢 11
附录一 参考文献 12
附录二 程序源代码 13
约瑟夫生死游戏
第一章 需求分析
1.1课程设计目的
课程设计目的是为学生提供了一个既动手又动脑, 独立实践的机会, 将课本上的理论知识和实际有机的结合起来, 锻炼学生的分析解决实际问题的能力。提高学生适应实际, 实践编程的能力。经过实践让学生理论和实际操作相结合, 更好的理解书面知识, 并在巩固的基础上融会所学认识。
1.2课程设计要求
约瑟夫生死游戏: 30个人围成一个圈由第一个人数起, 依次报数, 数到第九个人, 便把她剔除, 然后再从她的下一个人数起, 数到第九个人, 再将她剔除剩下15个乘客为止, 问那些位置将是被扔下大海的位置。课程设计要求是将30个人改为n,报数( 原为9) , 也改为任意正整数。根据得到的初始数据得到生者和死者的位置编号并输出。
1.3课程设计目标与总体方案
本实验设计的目标是运用循环链表来解决Josephu环问题, 其中运用了许多链表中的基本操作使改程序能不只解决一个Josephu的简单链表, 其中的Josephu函数则是用于, 运用C++程序编写程序, 实现队列的建立、 插入和删除基本功能, 在程序设计成功的基础上, 进一步深化理解队列的作用和实现原理。
1.4程序执行的命令
构造链表、 输入数据、 执行报数输出出列人的序号结束。
第二章 系统的功能
2.1系统功能说明
图1 系统功能程序图
2.2 系统功能解析
如上图所示, 本系统分为五个功能模块分别为: 构建链表, 确定n值, 更新链表, 输入, 输出。下面就每个功能进行详细说明:
( 1) 构建约瑟夫链表: 使整个游戏在链表中运行, 使得结点在删除时不需要移动大量的结点;
( 2) 确定n的值: 进而使链具化体, 从而能够构建一个具体的链表;
( 3) 更新链表: 对剔除结点后的链表进行重新连接又, 有构成了一个新的链表, 使得循环继续进行;
( 4) 输入: 输入n的值进行链表具体化, 输入间隔值m, 使得间隔被确定, 程序得以有效正确的进行;
( 5) 输出: 输出要剔除的结点的数值。
第三章 系统的设计
3.1Josphu链表的实现
Josphu链表——链式表示和实现约瑟夫( Josephu) 问题: 已知N个人围坐在一张圆桌周围( 不妨以1, 2, ……, N对每一个人依次编号) , 现在先从序号为K的人开始报数, 数到m的那个人出列, 她的下一个人又从1开始数, 报数到m的人出列……直到所有人都出出列为止。给出出列的顺序。
3.2循环链表
队列的顺序表示和实现和顺序栈相似, 在队列的顺序存储结构中, 除了用一组地址连续的存储单元依次存放从队列头到队列尾的元素之外, 尚需附设两个指针front和rear分别指示队列头元素及队列尾元素的位置。为了C语言中描述方便起见, 在此我们约定, 初始化建空队列时, 令front=rear=0,每当插入新的队列尾元素时, ”尾指针增1”; 每当删除队列头元素时, ”头指针增1”。因此, 在非空队列中, 头指针始终指向队列头元素, 而尾指针始终指向队列尾元素的下一个位置从上述分析可见, 在C++中不能用动态分配的一维数组来实现循环队列。如果用户的应用程序中设有循环队列, 则必须为它设定一个最大队列长度; 若用户无法预估所用队列的最大长度, 则宜采用链队列。
3.3 对程序的各个部分的详细介绍
编写本实验设计程序采用C++进行, 在Visual c++ 6.0环境下运行。
3.3.1利用类定义构造成员函数以及成员
template<class T>
class List
{
public:
List()
{
first=new LinkNode<T>;
first->link=first;
}
List(T x)
{
first=new LinkNode<T>(x);
first->link=first;
}
List(List<T>&L);
~List(){}
void Insert(int i,T x);
T getHead(){return first->data;}
LinkNode<T>* getfirst(){return first;}
void xiuf(LinkNode<T>* a){first=a;}
LinkNode<T>*Locate(int i);
protected:
LinkNode<T>*first;
};
3.3.2 定义成员函数
template<class T>
List<T>::List(List<T>&L)
{
T value;
LinkNode<T>*srcptr=L.getHead();
LinkNode<T>*destptr=first=new LinkNode<T>;
destptr->data=srcptr->data;
while(srcptr->link!=first)
{
value=srcptr->link->data;
destptr->link=new LinkNode<T>(value);
destptr=destptr->link;
srcptr=srcptr->link;
last=srcptr;
}
};
template<class T>
LinkNode<T>* List<T>::Locate(int i)
{
if(i<0)return NULL;
LinkNode<T>* current=first;
int k=1;
while(k<i)
{
current=current->link;
k++;
if(current==first)return NULL;
}
return current;
};
3.3.3创立含有n个结点的单循环链表
template<class T>
void List<T>::Insert(int i,T x)
{
LinkNode<T>* current=Locate(i);
if(current==NULL)return;
LinkNode<T>*newNode=new LinkNode<T>(x);
if(newNode==NULL)
{
cout<<"存储分配错误!"<<endl;
exit(1);
}
newNode->link=current->link;
current->link=newNode;
};
3.3.4 Josephu操作
Josephu操作为本程序的重点, 在本程序中我是利用了一个Josephu函数来解决该问题的, 该函数是经过不断的循环、 输出、 再循环、 再输出直到将Josephu链表中的一半元素被输出。函数如下:
template<class T>
void Josephus(List<T>& Js,int n,int m)
{
LinkNode<T> *p=Js.Locate(1),*pre;
int i,j;
for(i=1;i<=n/2;i++)
{
if(m==1)
{
cout<<"出列的人是:"<<p->data<<endl;
pre=p->link;
Js.xiuf(p->link);
delete p;
p=pre;
}
else
{
for(j=1;j<m;j++)
{
pre=p;
p=p->link;
}
cout<<"出列的人是"<<p->data<<endl;
pre->link=p->link;
if(p==Js.getfirst())Js.xiuf(p->link);
//if(p=Js.getlast())Js.movelast(pre);
delete p;
p=pre->link;
}
}
}
3.3.5主函数
void main()
{ List<int> clist(1);
int i,n,m;
cout<<"输入游戏者的人数和报数间隔: "<<endl;
cin>>n>>m;
for(i=1;i<n;i++)
{
clist.Insert(i,i+1);
}
Josephus(clist,n,m);
}
3.4程序的流程
3.4.1流程图
图2 程序流程图
3.4.2流程图的说明
开始进入程序, 先确定n的值, 然后, 根据n得知建立链表, 然后数数, 确定输出的位置, 输出数, 更新链表, 如果剩下的数小于等于n/2,则停止程序, 否则继续计数进行循环直至结束程序。
第四章 程序的运行结果图
4.1开始运行程序
程序的初始化
图3 程序初始化
4.2先键入参加游戏的人数及报数间隔
输入人数和报数间隔30 9
图4 确定n值及间隔值m
4.3按空格键运行程序
运行结果
图4.3运行结果
第五章 总结
致谢
附录一 参考文献
[1]谭浩强.《C++程序设计》.北京:清华大学出版社 .
[2]严蔚敏,吴伟民 .《数据结构》.北京:清华大学出版社.
[3]严蔚敏,吴伟民,米宁.《数据结构教程上机实验指导》.北京:清华大学出版社.
附录二 程序源代码
#include<iostream>
using namespace std;
template<class T>
struct LinkNode
{
T data;
LinkNode<T>*link;
LinkNode( T item)
{
data=item;
link=NULL;
}
};
template<class T>
class List
{
public:
List()
{
first=new LinkNode<T>;
first->link=first;
}
List(T x)
{
first=new LinkNode<T>(x);
first->link=first;
}
List(List<T>&L);
~List(){}
void Insert(int i,T x);
T getHead(){return first->data;}
LinkNode<T>* getfirst(){return first;}
void xiuf(LinkNode<T>* a){first=a;}
LinkNode<T>*Locate(int i);
protected:
LinkNode<T>*first;
};
template<class T>
List<T>::List(List<T>&L)
{
T value;
LinkNode<T>*srcptr=L.getHead();
LinkNode<T>*destptr=first=new LinkNode<T>;
destptr->data=srcptr->data;
while(srcptr->link!=first)
{
value=srcptr->link->data;
destptr->link=new LinkNode<T>(value);
destptr=destptr->link;
srcptr=srcptr->link;
last=srcptr;
}
};
template<class T>
LinkNode<T>* List<T>::Locate(int i)
{
if(i<0)return NULL;
LinkNode<T>* current=first;
int k=1;
while(k<i)
{
current=current->link;
k++;
if(current==first)return NULL;
}
return current;
};
template<class T>
void List<T>::Insert(int i,T x)
{
LinkNode<T>* current=Locate(i);
if(current==NULL)return;
LinkNode<T>*newNode=new LinkNode<T>(x);
if(newNode==NULL)
{
cout<<"存储分配错误!"<<endl;
exit(1);
}
newNode->link=current->link;
current->link=newNode;
};
template<class T>
void Josephus(List<T>& Js,int n,int m)
{
LinkNode<T> *p=Js.Locate(1),*pre;
int i,j;
for(i=1;i<=n/2;i++)
{
if(m==1)
{
cout<<"出列的人是:"<<p->data<<endl;
pre=p->link;
Js.xiuf(p->link);
delete p;
p=pre;
}
else
{
for(j=1;j<m;j++)
{
pre=p;
p=p->link;
}
cout<<"出列的人是"<<p->data<<endl;
pre->link=p->link;
if(p==Js.getfirst())Js.xiuf(p->link);
//if(p=Js.getlast())Js.movelast(pre);
delete p;
p=pre->link;
}
}
}
void main()
{
List<int> clist(1);
int i,n,m;
cout<<"输入游戏者的人数和报数间隔: "<<endl;
cin>>n>>m;
for(i=1;i<n;i++)
{ clist.Insert(i,i+1);
}
Josephus(clist,n,m);
}
展开阅读全文