中法计122班实验一.docx
- 文档编号:26563878
- 上传时间:2023-06-20
- 格式:DOCX
- 页数:13
- 大小:37.28KB
中法计122班实验一.docx
《中法计122班实验一.docx》由会员分享,可在线阅读,更多相关《中法计122班实验一.docx(13页珍藏版)》请在冰豆网上搜索。
中法计122班实验一
数据结构实验一
约瑟夫环问题
班级:
中法计122班
【实验内容】
约瑟夫(Joseph)问题的一种描述是:
编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码(正整数)。
开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。
报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。
试设计一个程序求出出列顺序。
利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。
m的初值为20;n=7,7个人的密码依次为:
3,1,7,2,4,8,4,首先m值为6(正确的出列顺序应为6,1,4,7,2,3,5)。
【实验目的】
掌握链表的基本操作:
插入、删除、查找等运算,能够灵活应用链表这种数据结构。
【程序清单】
#include
usingnamespacestd;
structpeople
{
intNUMBER;
intPASSWORD;//每个人的编号和密码
}eachNode;
template
classLink
{
private:
staticLink
public:
structpeopleelement;
Link*next;
Link(peopleelemval,Link*nextval=NULL)
{
element.NUMBER=elemval.NUMBER;
element.PASSWORD=elemval.PASSWORD;
next=nextval;
}
Link(Link*nextval=NULL)
{
next=nextval;
}
void*operatornew(size_t);//重载new函数。
voidoperatordelete(void*);//重载delete函数。
};
template
classLinkList
{
private:
Link
Link
Link
voidinitialize()
{
headNode=tailNode=sta=newLink
tailNode->next=headNode->next;//生成链表是要把它的头接点和尾接点连接起来构成循环链表。
//因为有一个空的头接点。
所以要把他的尾接点接到头接点的下一个指针。
}
voidremoveall()
{
while(headNode!
=NULL)
{
sta=headNode;
sta=sta->next;
deletesta;
}
}
public:
LinkList()
{
initialize();
}
~LinkList()
{
removeall();
}
boolinsert(constpeople&T);
boolremove(Elem&);
voidgetOut(int&,int&);
voidprevious();
boolappend(constpeople&T);
};
template
Link
:
freelist=NULL;//静态数据成员的初始化。
//重载的实现。
template
void*Link
:
operatornew(size_t)
{
if(freelist==NULL)
return:
:
newLink;
Link
freelist=freelist->next;
returntemp;
}
////当中的new和delete采用了重载函数。
//重载的实现
template
voidLink
:
operatordelete(void*ptr)
{
((Link
freelist=(Link
}
//插入函数。
template
boolLinkList
:
insert(constpeople&T)
{
sta->next=newLink
if(tailNode==sta)
{
tailNode=sta->next;
tailNode->next=headNode->next;
}
returntrue;
}
//从链表的尾端插入。
template
boolLinkList
:
append(constpeople&T)
{
tailNode=tailNode->next=newLink
returntrue;
}
template
boolLinkList
:
remove(Elem&it)
{
if(tailNode==headNode)
returnfalse;
if(sta->next==NULL)
{
it=sta->element.PASSWORD;
cout<
returntrue;
}
it=sta->next->element.PASSWORD;
cout<
Link
sta->next=temp->next;
if(temp==tailNode)
{
tailNode=sta;//当是尾接点的时候要把他的尾指针指向标记指针
}
deletetemp;
returntrue;
}
template
voidLinkList
:
previous()
{
if(sta->next!
=headNode)
sta=sta->next;
else
{
sta->next=headNode->next;
sta=sta->next;
}
}
//程序的主体//
template
voidLinkList
:
getOut(int&it,int&sum)
{
intsign,n=1;
sta=tailNode;//因为是从报到数的上一个人开始找到的删除点。
所以要记得从headNode的上一个接点tailNode开始。
cout<<"请输入第一个出列的人:
";
cin>>sign;//报数值。
if(sign>20)
{
cout<<"请重新输入(不大于20):
";
cin>>sign;
}
while(sum>0)
{
if(sign>sum&&sign>1)//为避免多次的循环找数通过取模可以节省时间。
sign=sign%sum;
if(sign==n||sum==1)
{
remove(it);
sign=it;
sum--;
n=0;//重新做标记从下一个人1开始。
}
else
previous();//找下个接点。
n++;
}
}
intmain()
{
cout<<"中法计122班-122930-徐彤坤\n";
LinkList
structpeopleT;
intitem,it,sum;
cout<<"您希望一共有多少人:
";
cin>>sum;
for(inti=1;i<=sum;i++)
{
cout<
";
cin>>item;
T.NUMBER=i;
T.PASSWORD=item;
A.append(T);//从尾插入的。
cout< } A.getOut(it,sum); return0; } 【算法的基本思想】 为了实现上述操作,应以单向循环链表为存储结构。 1. 基本操作: template 操作结果: 构造空链表,若成功就初始化每个人的相关信息 初始条件: 线性链表存在 操作结果: 释放指向出列的人的结点,并重新报数 2. 本程序包含三个模块: (1) 主程序模块; template voidLinkList : getOut(int&it,int&sum) { intsign,n=1; sta=tailNode;//因为是从报到数的上一个人开始找到的删除点。 所以要记得从headNode的上一个接点tailNode开始。 cout<<"请输入第一个出列的人: "; cin>>sign;//报数值。 if(sign>20) { cout<<"请重新输入(不大于20): "; cin>>sign; } while(sum>0) { if(sign>sum&&sign>1)//为避免多次的循环找数通过取模可以节省时间。 sign=sign%sum; if(sign==n||sum==1) { remove(it); sign=it; sum--; n=0;//重新做标记从下一个人1开始。 } else previous();//找下个接点。 n++; } (2) 插入函数: boolLinkList : insert(constpeople&T) { sta->next=newLink if(tailNode==sta) { tailNode=sta->next; tailNode->next=headNode->next; } returntrue; } 定义类模板: template classLink { private: staticLink public: structpeopleelement; Link*next; Link(peopleelemval,Link*nextval=NULL) { element.NUMBER=elemval.NUMBER; element.PASSWORD=elemval.PASSWORD; next=nextval; } Link(Link*nextval=NULL) { next=nextval; } (3) 释放结点模块; 【调试步骤】 m的初值为20;n=7,7个人的密码依次为: 3,1,7,2,4,8,4,首先m值为6(正确的出列顺序应为6,1,4,7,2,3,5)。 首先输入您希望的人数,然后一次输入对应人数的密码,然后再选择在您队列中第一个出列的人。 【运行结果】 【分析与思考】 通过这次实验,让我对链表的基本操作有了更好的认识,达到了实验目的。 在编写程序时我发现本程序的关键点看你是否把循环链表真的循环了,还有就是在删除接点的时候.要记得连接.特别是删除尾接点,做好这些了,就是在进行报数出列的时候对报数和做标记的处理.还有就是在当密码数大于个数是要进行取模减少循环次数.节约时间. 用单循环链表模拟约瑟夫环问题,循环链表是一种首尾相接链表,其特点是无须增加存储容量,仅对表的链接方式稍作改变,使表处理更加灵活,约瑟夫环问题就是用单循环链表处理的一个实际应用。 通过这个设计实例,了解了单链表和单循环链表的相同与不同之处,进一步加深了对链表结构类型及链表操作的理解
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 中法 122 实验