敢死队问题+数据结构课程设计Word格式文档下载.docx
《敢死队问题+数据结构课程设计Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《敢死队问题+数据结构课程设计Word格式文档下载.docx(15页珍藏版)》请在冰豆网上搜索。
当n=10输出结果为:
要求的位置是:
9
(二)、概要设计
算法思想:
本程序其实质是约瑟夫环问题,本次实验用了线性表和循环队列两种数据结构,并运用模块化的程序设计思想,算法的实现是这样的:
1.定义结构体类型
2.定义变量并初始化
3.线性表初始化
4.队员报数,是5的倍数出列
5.当队员数等于1时,输出
程序框图:
(三)、详细设计
宏定义:
#defineLIST_INIT_SIZE100
#defineLISTINCCREMENT10
数据类型定义:
typedefintElemType;
定义数据结构:
typedefstructKList/*定义数据结构体类型*/
{
ElemType*elem;
/*存储空间基址*/
intlength;
/*当前长度*/
intlistsize;
/*当前分配的存储容量(以sizeof(ElemType)为单位)*/
}SqList;
模块一:
创建线性表函数
SqListInitList_Sq()/*创建线性表函数*/
SqListL;
=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
/**/
if(!
printf("
Failinnewcreatlist"
),exit(0);
/*存储分配失败*/
else
{
=0;
/*空表长度为0*/
=LIST_INIT_SIZE;
/*初始存储容量*/
}
}
模块二:
线性表再分配函数
SqListListInsert_Sq(SqListL)/*线性表再分配函数*/
/*SqListL;
*/
int*newbase;
newbase=(ElemType*)realloc,
+LISTINCCREMENT)*sizeof(ElemType));
/*为顺序表增加一个大小为存储LISTINCCREMENT个数据元素的空间*/
newbase)printf("
Failinnewaddlist"
/*存储分配失败*/
=newbase;
/*新基址*/
+=LISTINCCREMENT;
/*增加存储容量*/
主模块:
实现总体功能
main()
ints,i,m,count=0;
/*声明变量*/
L=InitList_Sq();
Pleaseinputthetataloftheteam:
"
);
scanf("
%d"
&
m);
/*输入敢死队员总数*/
while(m!
=0)/*当输入为0时退出程序*/
while(m>
/*当顺序表当前分配的存储空间大小不足时进行再分配*/
L=ListInsert_Sq(L);
for(i=0;
i<
m;
i++)[i]=i+1;
/*为队员赋值*/
s=m;
i=0;
while(s>
1)/*当所剩敢死队员总数为1时,总循环结束*/
for(i=0;
i++)
if[i]!
=0)
{
count++;
if(count==5)/*报数循环*/
{
[i]=0;
/*表示队员出列*/
count=0;
/*计数器清零*/
s--;
/*敢死队员数-1*/
}
}
i++)/*输出*/
if[i]!
if([i]+2)%m==0)/**/
printf("
\nThewantedorderis%dth\n"
m);
else
[i]+2)%m);
Exitpleaseinput'
0'
OrGoon...\nPleaseinputthetataloftheteam:
思考:
本次设计问题的核心是如何输出,因为这影响到了程序的时间复杂度。
总模块的输出设计是这样实现的:
总是从第一个开始报数,报到5出列,直到剩下最后一个为止,然后就令这个位置为队长位置,队首为开始报数的位置,并按此设计输出即可。
这种方法大大的降低了时间复杂度,其复杂度为O(mn)。
(四)、程序调试及运行
程序调试过程中出现了下面的警告:
经查询错误为:
不可移动的指针(地址常数)赋值
最终发现是下面的定义错误造成的
在变量定义中int*newbase=0;
定义成了intnewbase=0;
经改正程序运行正常了.
数据测试如下:
时间复杂度为O(mn)
(五)、设计总结
通过这次课程设计我又学到了很多东西,如程序的模块化设计思想,同时也加深了对数据结构这门课程的理解和学会了如何在实际中应用数据结构编程。
我首先是用线性表来做的,开始的想法是想用试验的方法来查找到所要求的位置,即首先从第一号开始报数,然后检查最后剩下的一个是否是队首,然后从第二个开始报数……从第三个开始报数……直到所剩下的最后一个是队首。
虽然这种方法可以实现查找,可却是以消耗更多的时间为代价的,于是我又想到了这个方法:
这种方法大大的降低了时间复杂度,复杂度为O(mn)。
(六)、附件
程序源代码:
\n"
1.本程序输入队伍人数n为任意的,最终输出记数的初始位置,首先输入一个报数上限m,当达到报数上限时,那名士兵出列执行任务,从下个人开始记数,再次循环,直到只剩一人,得到其在队伍中的位置,通过数学思想求得题目要求即队长为首的情况下需要记数初始位置。
(1)构造链表;
(3)执行删除;
当n=10,m=5,输出结果为:
以单循环链表为存储结构,包含三个模块:
1.主程序模块
2.构造链表并初始化
3.删除结点
1.结点类型和指针类型
typedefstructnode
intdata;
structnode*next;
}LNode;
/*定义结点类型*/
LNode*p;
2.每个模块的分析:
主程序模块:
LNode*p;
intm,n,z,y;
do
printf("
Pleaseinputthepeoplenumber:
scanf("
n);
}
while(n<
=0);
printf("
Pleaseinputtheexcursion:
while(m<
if(n=1)
thepositionis:
1"
p=CREAT(n);
y=DELETE(p,m);
z=n-y+2;
if(z%n==0)/*排除特殊情况*/
printf("
\n%d\n"
z);
printf("
(n-y+2)%n);
}/*通过数学思想求得实验要求情况下的数值*/
2.构造单循环链表并初始化模块:
LNode*CREAT(intn)/*创建循环链表*/
LNode*s,*q,*t;
inti;
if(n!
t=q=(LNode*)malloc(sizeof(LNode));
q->
data=1;
/*生成第一个结点并使其data值为1*/
for(i=2;
=n;
{
s=(LNode*)malloc(sizeof(LNode));
/*自动生成结点*/
next=s;
next->
data=i;
/*给第i个结点赋值i*/
q=q->
next;
next=t;
}/*生成后续结点,并使其data值即为它所在链表(队伍)中的位置*/
returnt;
3.删除结点模块:
DELETE(LNode*t,intm)/*链表的删除*/
LNode*a;
inti;
while(t->
next!
=t)
for(i=1;
m-1;
i++)/*查找要删除结点的前一结点*/
t=t->
a=t->
t->
next=a->
free(a);
/*释放结点*/
}/*while循环依次删除被点到的士兵*/
return(t->
data);
(四).调试分析:
说明:
(1)本程序的运行环境是TC
(2)进入演示程序后显示提示信息:
Exitpleaseinput'
OrGoon
输入队伍总人数
输入间隔人数
结果显示:
Thewantedpositionisth
选择的位置
(3)调试
程序调试过程中遇到如下警告:
发现错误为if(m=1)
后改正为if(m==1)程序运行正确了,运行如下:
显示输出如图:
(3)由程序分析可得:
本程序时间复杂度为O(nm)!
(4)①在设计生成循环单链表时,考虑到程序结果需要士兵的位序,故将每个结点的data值设置为他们在队列中的位置,方便返回。
②在删除单链表时,如果在报数时直接数到出列士兵则不方便链表的删除,可设置i<
m-1找到出列士兵的前一位执行如下:
for(i=1;
③.在程序设计前,如果按原题所设,则需设队长为第一位,再分别测试从第几个开始才能符合条件。
现在改变思想,通过数学思想:
单循环链表本身是一个循环体,可先求出当从第一个出发的话,求出每隔m个出去一个最后是谁未出列,然后再设置它为链头,求出当他为队首时从第几个开始方能使其不出列。
(n-y+2)%n即可实现这功能!
通过这次课程设计我又学到了很多东西,如程序的模块化设计思想,同时也加深了对数据结构这门课程的理解和学会了如何在实际中应用数据结构.
这个方法是用单循环链表来做的,实现的方法是这样的:
首先从第一号开始报数,循环到指定的偏移位置删除结点,直至剩下一个结点。
然后设计输出,令这个位置为队长位置,队首为开始报数的位置,并按此输出即为所求。
t=q=(LNode*)malloc(sizeof(LNode));
q->
for(i=2;
s=(LNode*)malloc(sizeof(LNode));
q=q->
LNode*p;
intm,n,z,y;
scanf("
/*输入队员总数*/
while(n!
=0)/*当队员总数等于0时退出*/
Pleaseinputtheexcursion:
/*输入偏移数*/
if(m==1)
Thewantedpositionis1th.\n"
p=CREAT(n);
y=DELETE(p,m);
z=n-y+2;
if(z%n==0)/*排除特殊情况*/
printf("
Thewantedpositionis%dth: