数据结构实验一joseph.docx

上传人:b****4 文档编号:4305549 上传时间:2022-11-29 格式:DOCX 页数:14 大小:69.51KB
下载 相关 举报
数据结构实验一joseph.docx_第1页
第1页 / 共14页
数据结构实验一joseph.docx_第2页
第2页 / 共14页
数据结构实验一joseph.docx_第3页
第3页 / 共14页
数据结构实验一joseph.docx_第4页
第4页 / 共14页
数据结构实验一joseph.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

数据结构实验一joseph.docx

《数据结构实验一joseph.docx》由会员分享,可在线阅读,更多相关《数据结构实验一joseph.docx(14页珍藏版)》请在冰豆网上搜索。

数据结构实验一joseph.docx

数据结构实验一joseph

 

课程设计报告

课程设计名称数据结构课程设计

专业计算机科学与技术

班级计科三班

学  号XXXXXX

姓名XXXXXX

指导教师XXXXXX

成绩

 

数据结构课程设计

——《Joseph环》

目录

一、设计任务与要求1

1.1总体目标与任务要求1

1.2题目选择与目的意义1

1.3所选题目的主要工作1

二、需求分析2

2.1用户需求分析2

2.2功能需求分析2

2.3系统需求分析2

三、概要设计3

3.1各模块的算法设计说明3

函数流程图:

3

模块关系图:

4

3.2存储结构设计说明5

四、详细设计5

五、源代码7

六、运行结果分析9

算法的时空分析9

七、收获与体会11

八、主要参考资料11

 

一、设计任务与要求

1.1总体目标与任务要求

总体目标:

用C++软件设计一个程序用来求出一个序列的出列顺序。

要求:

利用单向循环链表存储结构实现这个过程,按照出列的顺序输出每一个人的编号。

1.2题目选择与目的意义

据说joseph在战争时期,与39个犹太人和他一个朋友躲到一个洞里,39个犹太人决定宁死也不被敌人抓到,于是他们决定了一个自杀方式,41个人排成圈,由第一个人开始报数,每报到三的人就必须自杀,依次循环直到每个人都自杀身亡。

但josrph和他的朋友并不想村从,于是他把自己和朋友安排到第16个位置和第31个位置,于是他们俩逃过了这个死亡游戏。

Joseph问题是个很由意思的问题,其意义在于它启发我们用一个循环的链来表示这个圈子,可以使用结构数组来构成一个循环链。

结构中有两个成员,其一为指向下一个人的指针,以构成环形的链;其二为该人的标记。

所以我们选择了这个题目。

1.3所选题目的主要工作

以单向循环链表的方式建立约瑟夫环。

建立输入处理输入数据,输入m的初值,n,建立单向链表,输入每个人的密码建立一个输出函数,将正确的出列顺序输出序列。

二、需求分析

2.1用户需求分析

编号是1,2,……,n的n个人按照顺时针方向围坐一圈,每个人只有一个密码(正整数)。

一开始任选一个正整数作为报数上限值m,从第一个仍开始顺时针方向自1开始顺序报数,报到m时停止报数。

报m的人出列,将他的密码作为新的m值,从他在顺时针方向的下一个人开始重新从1报数,如此下去,直到所有人全部出列为止。

设计一个程序来求出出列顺序。

2.2功能需求分析

各个模块间的调用关系如下:

 

2.3系统需求分析

系统软件:

Windows操作系统

开发软件:

MicrosoftVisualC++6.0

其他软件:

MicrosoftOfficeWord2003,AdobePhotoshopCS3

三、概要设计

3.1各模块的算法设计说明

函数流程图:

 

 

模块关系图:

 

joseph*creat(void),voidgame(joseph*head,intm),voidmain()部分函数流程图:

 

3.2存储结构设计说明

typedefstructNode

{

ElemTypedate;//编号

intmima;//密码

structNode*next;

}Node,*LinkList;

单向循环链表:

LinkListH;//表头指针

Node*Q,*Pre;//*Q指新建结点,*pre指向当前工作结点

Q=(Node*)malloc(sizeof(Node));

构造函数:

voidInitList(LinkList*H);//初始化循环链表

voidInPut(LinkListH,int*A);//插入结点

voidDelList(LinkListH,int*x,int*a);//删除结点

四、详细设计

typedefstructLnode{//节点类型

ElemTypedata;

StructLnode*next;

}*Link,*Position;

typedefstruct{//链表类型

Linkhead,tail;//分别指向线性链表中的头结点和最后一个结点

Intlen;//只是线性链表中的数据元素

}LinkList;

StatusMakeNode(Link&p,ElemTypee);

//分配由p指向的值为e的结点,并返回OK;若分配失败,则返回ERROR

voidFreeNode(Link&p);

//释放p所指接点

StatusInitList(LinkList&L);

//构造一个空的线性表L

StatusDestroyList(LinkList&L);

//销毁线性表L,L不再存在

StatusClearList(LinkList&L);

//将线性表L从之唯恐表,并释放原链表的结点空间

StatusInsFirst(Linkh,Links);

//已知h指向线性链表的头结点,将s所直接点插入在第一个结点之前

StatusDelFirst(Linkh,Link&q);

//已知h指向线性表的头结点,删除链表中的第一个结点并以q返回

StatusAppend(LinkList&L,Links);

//将指针s所指(彼此以指针项链)的一串结点链接在线性链表L的最后一个结点

//之后,并改变链表L的尾指针指向新的尾节点

StatusRemove(LinkList&L,Link&q);

//删除线性链表L中的尾结点并以q返回,改变链表L的尾指针只想新的尾结点

StatusInsBefore(LinkLIst&L,Link&p,Links);

//已知p指向线性链表L中的一个结点,将s所指结点插入在p所指结点之前,

//并修改指针p指向新插入的结点

StatusInsAfter(LinkLIst&L,Link&p,Links);

//已知p指向线性链表L中的一个结点,将s所指结点插入在p所指结点之后,

//并修改指针p指向新插入的结点

StatusSetCurElem(Link&p,ElemTypee);

//已知p指向线性链表中的一个结点,用e更新p所指结点中的数据元素的值

ElemTypeGetCurElem(Linkp);

//已知p指向线性链表中的一个结点,返回p所指结点中数据元素的值

StatuslistEmpty(LinkListL);

//若线性链表L为空表,则返回TRUE,否则返回FALSE

intListLength(LinkListL);

//返回线性链表L中元素个数

PositionGetHead(LinkListL);

//返回线性链表L中头结点的位置

PositionGetLast(LinkListL);

//返回线性链表L中最后一个结点的位置

PositionPriorPos(LinkListL,Linkp);

//已知p指向线性链表L中的一个结点,返回p所指结点的直接前驱的位置‘

//若无前驱,则返回NULL

PositionNextPos(LinkListL,Linkp);

//已知p指向线性链表L中的一个结点,返回p所指结点的直接后继的位置‘

//若无后继,则返回NULL

StatusLocatePos(LinkListL,intI,Link&p);

//返回p指示线性链表L中的第I个节点的位置并返回OK,i值不合法时返回ERROR

PositionLocateElem(LinkListL,ElemTypee,Status(*compare)(ElemType,ElemType));

//返回线性链表L中的第1个与e满足函数compare()判定关系的元素的位置,

//若不存在这样的元素,则返回NULL

StatusListTraverse(LinkListL,status(*visit)());

//依次对L的每个元素调用函数visit()。

一旦visit()失败,则操作失败

五、源代码

#include

#include

#include

#include

#include

typedefstructajose

{

intnum;

intcode;

}joseph;structajose*next;

joseph*creat(void)

{

joseph*head,*p1,*p2;

inti=0,code;

head=(joseph*)malloc(sizeof(joseph));

p2=p1=(joseph*)malloc(sizeof(joseph));

head->next=NULL;

cout<<"请输入第"<

"<

scanf("%d",&code);

while(code)

{

i++;

p1=(joseph*)malloc(sizeof(joseph));

p1->num=i;

p1->code=code;

if(i==1)

head->next=p1;

else

p2->next=p1;

p2=p1;

cout<<"请输入第"<

"<

scanf("%d",&code);

}

p2->next=head->next;

head->num=i;

printf("建立成功!

~\n");

returnhead;}

voidgame(joseph*head,intm)

{

joseph*p1,*p2;

inti=1;

p2=head;

p1=head->next;

while(head->num>1)

{

if(i==m)

{

p2->next=p1->next;

m=p1->code;

i=1;

printf("%3d",p1->num);

free(p1);

p1=p2->next;//p1指向输出结点

head->num--;

continue;

}

else

{

i++;

p2=p1;

p1=p1->next;//将p1指针指向所要输出的结点的前一结点

}

}

printf("%3d",p1->num);

return;

}

voidmain()

{

joseph*head;

intm;

head=creat();

printf("请输入m的值m:

");

scanf("%d",&m);

game(head,m);

getch();

printf("\njoseph环单向循环链表结束\n");

}

六、运行结果分析

由于刚开始忽略了该链表没有头结点这样一个特殊性,没有把第一个结点单独拿出来建立,因而出现了一些逻辑上的错误

程序写完后发现所有基本操作的结果均不能够返回到主函数,后通过XX百科和以前的C教材知道要用传址的方式调用,但是具体实现起来还是耗费了不少的时间

算法的时空分析

该程序不占用额外空间,因此空间复杂度是O(n)的,基本操作中,Destroy操作是O(n)的,Next_m操作是O(m)的,其余的操作都是O

(1)的,整个程序的时间复杂度是O(n*m)的

 

七、收获与体会

通过学习和实践,使我明白在进行面向过程的程序设计时,一般首先考虑程序所要实现的功能,然后设计为实现这些功能所必须采取的步骤,这些步骤就是过程。

如果一个过程比较复杂而不能直接使用已有的抽象进行实现,则对这个过程进行分解,使分解之后的每一步(更低级的过程)能够直接对应着一条语句。

通过将分解之后的一系列过程封装在一个函数抽象中,程序员在特定的时刻只关心有限的细节,这个新的函数抽象比其较低级的抽象更接近问题求解的过程,因而,能够很好地映射问题求解中的过程。

如果这个过程出现在许多问题求解中,那么,这个函数抽象就可能被重复利用。

由于是第一次用“以数据结构为中心”的思想编程,所以并不是很习惯,在主函数中还是充斥着很多基本语句,以后仍要多多练习。

八、主要参考资料

[1]JamesP.Cohoon&JackW.Davidson.《C++程序设计》.电子工业出版社

[2]严蔚敏.《数据结构(C语言版)》.清华大学出版社

[3]姚云鸿.《程序设计与数据结构》.清华大学出版社

 

指导教师签字:

年月日

#include

#include

usingnamespacestd;

typedefstructCirList

{

intnum,pwd;

structCirList*next;

}CirList,*LCirList;

intmain()

{

intm,n;//max为报数上限,num为人数。

inti,j;

printf("Pleaseentern=");

scanf("%d",&n);

printf("Pleaseenterm=");

scanf("%d",&m);

LCirListhead,tail,p,q;//head为头节点指针,tail为尾节点指针,p为当前指针的前一指针,q为当前指针。

head=(CirList*)malloc(sizeof(CirList));

p=head;

for(i=1;i

{

q=(CirList*)malloc(sizeof(CirList));

p->next=q;

p=q;

}

tail=q;

tail->next=head;//建立num个节点的循环链表。

p=head;

for(i=1;i<=n;i++)

{

p->num=i;

printf("PleaseenterNo.%d'spassword:

",i);

scanf("%d",&(p->pwd));

p=p->next;

}//输入密码。

printf("result:

");

p=tail;

for(i=1;i<=n;i++)

{

for(j=1;j

p=p->next;

q=p->next;

m=q->pwd;

printf("%d",q->num);

p->next=q->next;//删除元素

free(q);

}//输出编号。

return0;

}

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 表格类模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1