算法与数据结构 课程设计.docx
- 文档编号:24037732
- 上传时间:2023-05-23
- 格式:DOCX
- 页数:35
- 大小:92.02KB
算法与数据结构 课程设计.docx
《算法与数据结构 课程设计.docx》由会员分享,可在线阅读,更多相关《算法与数据结构 课程设计.docx(35页珍藏版)》请在冰豆网上搜索。
算法与数据结构课程设计
*******************
实践教学
*******************
兰州理工大学
计算机与通信学院
2012年春季学期
算法与数据结构课程设计
题目:
敢死队问题
专业班级:
姓名:
学号:
指导教师:
成绩:
_______________
目录
摘要1
前言2
正文3
1.采用类c语言定义相关的数据类型3
2.各模块的伪码算法6
3.函数的调用关系图10
4.调试分析11
5.测试结果11
6.源程序(带注释)13
总结22
参考文献23
致谢24
附件Ⅰ部分源程序代码25
摘要
有M个敢死队员要炸掉敌人的一碉堡,谁都不想去,排长决定用轮回数数的办法来决定哪个战士去执行任务。
如果前一个战士没完成任务,则要再派一个战士上去。
现给每个战士编一个号,大家围坐成一圈,随便从某一个战士开始计数,当数到5时,对应的战士就去执行任务,且此战士不再参加下一轮计数。
如果此战士没完成任务,再从下一个战士开始数数,被数到第5时,此战士接着去执行任务。
以此类推,直到任务完成为止。
通过该题目的设计过程,可以加深理解线性表及栈的逻辑结构、存储结构,掌握线性表及栈上基本运算的实现,进一步理解和熟练掌握课本中所学的各种数据结构,学会如何把学到的知识用于解决实际问题,培养学生的动手能力。
关键词:
敢死队;数据结构;线性表;循环队列;循环链表
算法设计:
以单循环链表为存储结构,包含三个模块:
1.主程序模块
2.构造链表并初始化
3.删除结点
前言
课程设计是综合性比较强和比较复杂的作业,通常需要比较宽的知识面,花费比较多的时间,具有比较高的能力以及要付出比较多的努力才能完成的作业。
我们充分认识到课程设计在教学过程中的重要性,通过课程设计可使我们更好的掌握和理解复杂的概念,促进理论知识学习,提高专业技能,培养思想素养和激发创新精神。
本课题运用C++语言进行开发,C++语言能够简单的进行编译一些程序,来实现对一些问题的解决。
它虽然比较简单的处理一些问题,但却有更高的效率。
经过这一个学期对《数据结构》的学习,我们都学到了不少东西,可能有些学的还不够理想,但无论如何这些知识都为我们的下一步学习打下了坚实的基础。
做这么一个课程设计,一方面是为了检查我们一个学期以来的学习成果,另一方面也是为了让我们进一步的掌握和运用它,同时也让我们认清自己的不足之处和薄弱环节,加以弥补和加强。
这次课程设计是对我们学习了C语言与C++课程的总结,同时也是对我们所学知识的运用和检验。
通过这次课设暴露出了我的诸多问题,这些问题充分体现了我在以前学习中的缺点和不足之处,使我明确了今后在学习中要克服的问题和需要加强的地方。
正文
采用类c语言定义相关的数据类型
(一)节点定义:
(1)typedefstructnode
{
intdata,DELETE;
structnode*next;
}LNode;/*定义结点类型
typedefstructKList/*定义数据结构体类型*/
{
ElemType*elem;/*存储空间基址*/
intlength;/*当前长度*/
intlistsize;/*当前分配的存储容量(以sizeof(ElemType)为单位)*/
}SqList;
typedefstruct{
intdata[QueueSize];
intfront;
intrear;
intcount;//计数器,记录队中元素总数
}CirQueue;
(2)对链表的操作函数
LNode*CREAT(intn)/*创建循环链表*/
{
LNode*s,*q,*T;
inti;
if(n!
=0)
{
T=q=(LNode*)malloc(sizeof(LNode));
q->data=1;/*生成第一个结点并使其data值为1*/
for(i=2;i<=n;i++)
{
s=(LNode*)malloc(sizeof(LNode));
q->next=s;
q->next->data=i;/*赋值*/
q=q->next;
}
q->next=T;
}
returnT;
}
intDELETE(LNode*T,intm)/*链表的删除*/
{
LNode*a;inti;
while(T->next!
=T)
{
for(i=1;i T=T->next; a=T->next; T->next=a->next; free(a); T=T->next; } printf("\n"); return(T->data); } 对线性表的操作函数 typedefintElemType; typedefstructKList/*定义数据结构体类型*/ { ElemType*elem;/*存储空间基址*/ intlength;/*当前长度*/ intlistsize;/*当前分配的存储容量(以sizeof(ElemType)为单位)*/ }SqList; intInitList_Sq(SqList&L)/*创建线性表函数*/ { L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType)); if(! L.elem) { printf("存储分配失败"); returnERROR;} else { L.length=0;/*空表长度为0*/ L.listsize=LIST_INIT_SIZE; returnOK;/*初始存储容量*/ } } intListInsert_Sq(SqList&L)/*线性表再分配函数*/ { /*SqListL;*/ int*newbase; newbase=(ElemType*)realloc(L.elem, (L.listsize+LISTINCCREMENT)*sizeof(ElemType)); /*为顺序表增加一个大小为存储LISTINCCREMENT个数据元素的空间*/ if(! newbase) {printf("存储分配失败"); returnERROR;} else { L.elem=newbase;/*新基址*/ L.listsize+=LISTINCCREMENT; /*增加存储容量*/ returnOK; } } 对队列的操作函数: typedefstruct{ intdata[QueueSize]; intfront;//头指针 intrear;//尾指针 intcount;//计数器,记录队中元素总数 }CirQueue; //置队列空 IntInitial(CirQueue*Q) {//将顺序队列置空 Q->front=Q->rear=0; Q->count=0;//计数器置0 } //判队列空 intIsEmpty(CirQueue*Q) { returnQ->front==Q->rear; } //判队列满 intIsFull(CirQueue*Q) { returnQ->rear==QueueSize-1+Q->front; } //进队列 voidEnQueue(CirQueue*Q,intx) { if(IsFull(Q)) { printf("队列上溢");//上溢,退出运行 exit (1); } Q->count++;//队列元素个数加1 Q->data[Q->rear]=x;//新元素插入队尾 Q->rear=(Q->rear+1)%QueueSize;//循环意义下将尾指针加1 } //出队列 intDeQueue(CirQueue*Q) { inttemp; if(IsEmpty(Q)) { printf("队列为空");//下溢,退出运行 exit (1); } temp=Q->data[Q->front]; Q->count--;//队列元素个数减1 Q->front=(Q->front+1)%QueueSize;//循环意义下的头指针加1 returntemp; } 各模块的伪码算法 算法描述: IntInitial(CirQueue*Q) {//将顺序队列置空 } //判队列空 intIsEmpty(CirQueue*Q) { returnQ->front==Q->rear; } //判队列满 intIsFull(CirQueue*Q) { returnQ->rear==QueueSize-1+Q->front; } //进队列 voidEnQueue(CirQueue*Q,intx) { if(IsFull(Q)) { } } //出队列 intDeQueue(CirQueue*Q) { inttemp; if(IsEmpty(Q)) { } } intmain() { printf("_____________________________________\n"); printf("|1.循环链表|\n"); printf("|2.线性表|\n"); printf("|3.循环队列|\n"); printf("|4.退出|\n"); printf("_____________________________________\n"); if(opt>4||opt<1) { } switch(opt) { case1: printf("您使用是循环链表储存结构\n\n"); if(num<1) { } if(m>num||m<1) { } else { if(z%num==0) else break; case2: printf("您使用的是线性表储存结构\n\n"); if(num<1) { } InitList_Sq(L); while(num>L.listsize)/*当顺序表当前分配的存储空间大小不足时进行再分配*/ for(i=0;i while(s>1)/*当所剩敢死队员总数为1时,总循环结束*/ { for(i=0;i if(L.elem[i]! =0) { if(count==5)/*报数循环*/ { } } } for(i=0;i if(L.elem[i]! =0) if((num-L.elem[i]+2)%num==0) else break; case3: printf("您使用的是循环队列储存结构\n\n"); CirQueues; if(num<1) { } for(start=1;start<=num;start++)//start为测试起点 { for(i=1;i<=num;i++) { } for(i=1;i { } while(count { for(i=1;i<5;i++) { } } if(s.data[s.front]==1) break; } break; case4: exit(0); break; } } 函数的调用关系图 调试分析 调试中遇到的问题及对问题的解决方法 (1)本程序的运行环境是c++6.0 (2)①在设计生成循环单链表时,考虑到程序结果需要士兵的位序,故将每个结点的data值设置为他们在队列中的位置,方便返回。 ②在删除单链表时,如果在报数时直接数到出列士兵则不方便链表的删除,可设置i for(i=2;i<=M-1;i++)/*查找要删除结点的前一结点*/ { lnode*q=newlnode; q->num=i; p->next=q; p=q; } lnode*t=newlnode; t->num=M; p->next=t; p=t; t->next=l.cl; ③.在程序设计前,如果按原题所设,则需设队长为第一位,再分别测试从第几个开始才能符合条件。 现在改变思想,通过数学思想: 单循环链表本身是一个循环体,可先求出当从第一个出发的话,求出每隔m个出去一个最后是谁未出列,然后再设置它为链头,求出当他为队首时从第几个开始方能使其不出列。 (n-y+2)%n即可实现这功能! 本程序输入队伍人数n为任意的,最终输出记数的初始位置,首先输入一个报数上限m,当达到报数上限时,那名士兵出列执行任务,从下个人开始记数,再次循环,直到只剩一人,得到其在队伍中的位置,通过数学思想求得题目要求即队长为首的情况下需要记数初始位置。 (3)调试运行 (4)算法的时间复杂度和空间复杂度 时间复杂度为: T(n)=O(mn); 空间复杂度为: S(n)=O(f(n)); 测试结果 进入用户主界面,选者实现结果的方法 以10个队员,死亡数字为5来运行,结果如下 选择第2项功能,运用线性表储存结构 选择第3项功能,运用循环队列来实现结果 源程序(带注释) 模块 (一) //敢死队问题,使用单向循环链表 #include usingnamespacestd; typedefstructnode{ intnum; node*next; }lnode;//定义结点 typedefstruct{ lnode*cl; }linklist; voidmain() { intM; inti; intstart,count; linklistl; cout<<"enterthevalueofM: "; cin>>M; for(start=1;start<=M;start++)//start为测试起点 { //初始化链表 lnode*p=newlnode; l.cl=p; l.cl->num=1; for(i=2;i<=M-1;i++) { lnode*q=newlnode; q->num=i; p->next=q; p=q; } lnode*t=newlnode; t->num=M; p->next=t; p=t; t->next=l.cl; //找到起点 p=l.cl; for(i=1;i { p=p->next; } count=0; while(count<=M-1) { for(i=1;i<5;i++) { t=p; p=t->next; } t->next=p->next; count++; p=t->next; } if(p->num==1) break; } cout<<"startfrom: "< } ///敢死队问题,使用线性表 #defineLIST_INIT_SIZE1000 #defineLISTINCCREMENT100 #defineOK1 #defineERROR0 typedefintElemType; typedefstructKList/*定义数据结构体类型*/ { ElemType*elem;/*存储空间基址*/ intlength;/*当前长度*/ intlistsize;/*当前分配的存储容量(以sizeof(ElemType)为单位)*/ }SqList; intInitList_Sq(SqList&L)/*创建线性表函数*/ { L.elem=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType)); if(! L.elem) { printf("存储分配失败"); returnERROR;} else { L.length=0;/*空表长度为0*/ L.listsize=LIST_INIT_SIZE; returnOK;/*初始存储容量*/ } } intListInsert_Sq(SqList&L)/*线性表再分配函数*/ { /*SqListL;*/ int*newbase; newbase=(ElemType*)realloc(L.elem, (L.listsize+LISTINCCREMENT)*sizeof(ElemType)); /*为顺序表增加一个大小为存储LISTINCCREMENT个数据元素的空间*/ if(! newbase) {printf("存储分配失败"); returnERROR;} else { L.elem=newbase;/*新基址*/ L.listsize+=LISTINCCREMENT; /*增加存储容量*/ returnOK; } } ////敢死队问题,使用循环队列 #include usingnamespacestd; #defineQueueSize100//假定预分配的队列空间最多为100个元素 //typedefintDataType;//假定队列元素的数据类型为字符 typedefstruct{ intdata[QueueSize]; intfront;//头指针 intrear;//尾指针 intcount;//计数器,记录队中元素总数 }CirQueue; //置队列空 voidInitial(CirQueue*Q) {//将顺序队列置空 Q->front=Q->rear=0; Q->count=0;//计数器置0 } //判队列空 intIsEmpty(CirQueue*Q) { returnQ->front==Q->rear; } //判队列满 intIsFull(CirQueue*Q) { returnQ->rear==QueueSize-1+Q->front; } //进队列 voidEnQueue(CirQueue*Q,intx) { if(IsFull(Q)) { printf("队列上溢");//上溢,退出运行 exit (1); } Q->count++;//队列元素个数加1 Q->data[Q->rear]=x;//新元素插入队尾 Q->rear=(Q->rear+1)%QueueSize;//循环意义下将尾指针加1 } //出队列 intDeQueue(CirQueue*Q) { inttemp; if(IsEmpty(Q)) { printf("队列为空");//下溢,退出运行 exit (1); } temp=Q->data[Q->front]; Q->count--;//队列元素个数减1 Q->front=(Q->front+1)%QueueSize;//循环意义下的头指针加1 returntemp; } 主模块 intmain() { SqListL; ints,i,m,count=0;/*声明变量*/ LNode*p; intz,y; intnum; intopt; abc: printf("_____________________________________\n"); printf("|1.循环链表|\n"); printf("|2.线性表|\n"); printf("|3.循环队列|\n"); printf("|4.退出|\n"); printf("_____________________________________\n"); printf("请选择实现结果的方法: (1~4)\n\n"); scanf("%d",&opt); if(opt>4||opt<1) { printf("输入有误请重新输入\n"); gotoabc; } switch(opt) { case1: system("cls"); printf("您使用是循环链表储存结构\n\n"); efg: printf("请输入敢死队的人数: \n"); scanf("%d",&num); if(num<1) { printf("输入有误请重新输入\n"); gotoefg; } printf("请输入用来计数数字\n"); m: scanf("%d",&m); if(m>num||m<1) {printf("输入有误请重新输入"); gotom;} else { p=CREAT(num);
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法与数据结构 课程设计 算法 数据结构
![提示](https://static.bdocx.com/images/bang_tan.gif)