数据结构课程设计报告报告八皇后和停车场文档格式.docx
《数据结构课程设计报告报告八皇后和停车场文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计报告报告八皇后和停车场文档格式.docx(25页珍藏版)》请在冰豆网上搜索。
进入界面后,就会提示输入字符串的输入形式,在八皇后求解程序中,只要你选择输出解的格式,选择1则显示为每一列皇后的放置的行数,,选择2则显示的是以矩阵形式形象的显示皇后的放置位置,选择0则退出程序的调试。
在调试结果中,1的位置也就表示了该皇后应该所在的位置,0代表了空位置。
1.4概要设计
本课件学生是用循环递归循环来实现的,分别一一测试了每一种摆法,并把它拥有的92种变化表现出来。
在这个程序中,我的主要思路以及思想是这样的:
1.4.1解决冲突问题
这个问题包括了行,列,两条对角线;
列:
当第I行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以I为下标的标记置为被占领状态;
对角线:
对角线有两个方向。
在这我把这两条对角线称为:
主对角线和从对角线。
在同一对角线上的所有点(设下标为(i,j)),要么(i+j)是常数,要么(i-j)是常数。
因此,当第I个皇后占领了第J列后,要同时把以(i+j)、(i-j)为下标的标记置为被占领状态。
1.4.2数据结构的实现
而对于数据结构的实现,学生则是着重于:
数组a[I]:
a[I]表示第I个皇后放置的列;
I的范围:
1..8;
对角线数组:
b[j](主对角线),c[j](从对角线),根据程序的运行,去决定主
从对角线是否放入皇后
1.4.3流程图
图1-1算法流程图
1.5详细设计
解析:
递归实现n皇后问题。
算法分析:
数组a、b、c分别用来标记冲突,a数组代表列冲突,从a[0]~a[7]代表第0列到第7列。
如果某列上已经有皇后,则为1,否则为0。
数组b代表主对角线冲突,为b[i-j+7],即从b[0]~b[14]。
如果某条主对角线上已经有皇后,则为1,否则为0。
数组c代表从对角线冲突,为c[i+j],即从c[0]~c[14]。
如果某条从对角线上已经有皇后,则为1,否则为0。
代码如下:
#include<
stdio.h>
staticcharQueen[8][8];
staticinta[8];
staticintb[15];
staticintc[15];
staticintiQueenNum=0;
//记录总的棋盘状态数
voidqu(inti);
//参数i代表行
intmain()
{
intiLine,iColumn;
//棋盘初始化,空格为*,放置皇后的地方为@
for(iLine=0;
iLine<
8;
iLine++)
{
a[iLine]=0;
//列标记初始化,表示无列冲突
for(iColumn=0;
iColumn<
iColumn++)
Queen[iLine][iColumn]='
*'
;
}
//主、从对角线标记初始化,表示没有冲突
15;
b[iLine]=c[iLine]=0;
qu(0);
return0;
}
voidqu(inti)
intiColumn;
if(a[iColumn]==0&
&
b[i-iColumn+7]==0&
c[i+iColumn]==0)
//如果无冲突
Queen[i][iColumn]='
@'
//放皇后
a[iColumn]=1;
//标记,下一次该列上不能放皇后
b[i-iColumn+7]=1;
//标记,下一次该主对角线上不能放皇后
c[i+iColumn]=1;
//标记,下一次该从对角线上不能放皇后
if(i<
7)qu(i+1);
//如果行还没有遍历完,进入下一行
else//否则输出
//输出棋盘状态
printf("
第%d种状态为:
\n"
++iQueenNum);
%c"
Queen[iLine][iColumn]);
);
\n\n"
//如果前次的皇后放置导致后面的放置无论如何都不能满足要求,则回溯,重置
a[iColumn]=0;
b[i-iColumn+7]=0;
c[i+iColumn]=0;
}
1.6调试分析及测试
1.6.1遇到的问题及解决方法
由于对八个皇后放置的位置不能一次确定,而且前一个皇后的放置位置直接影响着后面的放置位置,使程序调试时要花费不少时间。
本程序有些代码重复出现,显得程序的有些代码看起来很杂乱。
但其中最主要的问题是逻辑错误导致程序死循环或不循环或循环一小部分,但是编译时却没有错误,就是没有正确的输出答案。
1.6.2算法的时空分析
该算法的运行时间和和皇后的放置方法成正比,在最好情况下的时间和空间复杂度均为O
(1),在最差情况下均为O(n*n),平均情况在它们之间。
1.6.3程序模块构架
本程序模块划分比较合理,且利用指数组存储棋盘,操作方便。
至于整体的系统架构,为了简单起见,这样的系统可以分成两个模块,第一个模块是负责模拟问题、提供算法,而另外一个模块则致力于窗口演示,是一个窗体应用程序
1.6.4程序使用说明
本程序的运行环境为DOS操作系统
进入演示程序后即显示文本方式的用户界面
进入界面后,就会提示输入字符串的输入形式,在八皇后求解程序中,只要你选择输出解的格式,选择1则显示为每一列皇后的放置的行数,,选择2则显示的是以矩阵形式形象的显示皇后的放置位置,选择3则退出程序的调试。
1.6.5测试结果
图1-2初步运行界面
图1-3位置标明每一行皇后放置的列数
图1-4位置标明每一行皇后放置的列数
图1-5视图矩阵形式显示皇后位置
第2章停车场管理问
2.1要解决的问题
停车场是一条可以停放n辆车的狭窄通道,且只有一个大门汽车停放安到达时间的先后依次由北向南排列(大门在最南端,最先到达的第一辆车停在最北端)若停车场已经停满n辆车,后来的汽车在便道上等候,一旦有车开走,排在便道上的第一辆车可以开入;
当停车场的某辆车要离开时,停在他后面的车要先后退为他让路,等它开出后其他车在按照原次序开入车场,每两停在车场的车要安时间长短缴费。
要求:
以栈模拟停车场,以队列车场外的便道,按照从终端输入的数据序列进行模拟管理。
每一组数据包括三个数据项:
汽车“到达”或“离去”信息、汽车牌照号码、以及到达或离去的时刻。
对每一组数据进行操作后的信息为:
若是车辆到达,则输出汽车在停车场的内或便道上的位置:
若是车辆离去则输出汽车在停车场内的停留时间和应缴纳的费用(在便道上的停留时间不收费)。
栈以顺序结构实现,队列以链表结构实现。
2.2基本要求
2.2.1解决问题的思路及要求
以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理。
每一组输入数据包括三个数据项:
汽车到达或离去信息,汽车牌照号码以及到达或离去的时刻。
对每一组输入数据进行操作后的输出信息为:
在停车场内停留的时间和应交纳的费用(在便道上停留的时间不收费)。
2.2.2对栈的要求
需要另设一个栈,临时停放为离去的汽车让路而从停车场退出来的汽车,也
用顺序存储结构实现。
栈中每个元素表示一辆汽车,包含两个数据项:
汽车的牌照号码和进入停车场的时刻
2.2.3算法流程图
图2-1算法流程图
2.4算法基本思想描述
由于停车场是一个狭窄通道,而且只有一个大门可供汽车进出,问题要求汽车停车场内按车辆到达时间的先后顺序,依次由北向南排列。
由此很容易联想到数据结构中的堆栈模型,因此可首先设计一个堆栈,以堆栈来模拟停车场,我设计用顺序存储结构来存储停车场内的车辆信息,并给车辆按进栈顺序编号,当停车场内某辆车要离开时,在他之后进入的车辆必须先退出车场为它让路,待该辆车开出大门外,其他车辆再按原次序进入停车场。
这是个一退一进的过程,而且让道的汽车必须保持原有的先后顺序,因此可再设计一个堆栈,以之来暂时存放为出站汽车暂时让道的汽车。
当停车场满后,继续进来的汽车需要停放在停车场旁边的便道上等候,若停车场有汽车开走,则按排队的先后顺序依次进站,最先进入便道的汽车将会最先进入停车场,这完全是一个先进先出模型,因此可设计一个队列来模拟便道,队列中的数据元素设计成汽车的车牌号,并以链表的形式存储。
另外,停车场根据汽车在停车场内停放的总时长来收费的,在便道上的时间不计费,因此必须记录车辆进入停车场时的时间和车辆离开停车场时的时间,然后计算、显示费用情况。
2.5概要设计
2.5.1栈的抽象数据类型
ADTstack{
数据对象:
D={aiai∈charset,I=1,2,……,n,n=0}
数据关系:
R1={ai-1,aiai-1,ai∈D,I=2……,n}
基本操作:
Initstack(&
S)
操作结果:
构造一个空栈S。
DestroyStack(&
初始条件:
栈S已经存在。
销毁栈S。
ClaerStack(&
将S清空为空栈。
StackLength(&
返回栈S的长度。
StackEmpty(&
若S为空栈,则返回TURE,否则返回FALSE。
GetTop(S,&
e)
若栈S不空,则以e返回栈顶元素。
Push(&
S,e)
在栈S的栈顶插入新的栈顶元素e。
Pop(&
S,&
删除S的栈顶元素,并以e返回其值。
StackTraverse(S,visit())
从栈底到栈顶依次对S中的每个元素调用函数visit()。
}ADTstack
2.5.2链式队列的抽象数据类型
typedefstructQnode{
QelemTypedata;
StructQnodenext;
}Qnode,QueuePtr;
typedefstruct{
QueuePtrfront;
队头指针
QueuePtrrear;
队尾指针
ADTQueue{
D={aiai∈ElemSet,i=1,2,……,n,n=0}
R1={ai-1,aiai-1,ai∈D,i=2,……,n}
约定中端为队列头,后端为队列尾。
InitQueue(&
Q)
构造一个空队列Q。
DestroyQueue(&
队列Q已经存在。
队列Q被销毁,不再存在。
ClearQueue(&
将Q清为空队列。
QueueEmpty(Q)
若Q为空队列,则返回TRUE,否则FALSE。
QueueLength(Q)
返回Q的元素个数,即队列的长度。
GetHead(Q,&
Q为非空队列。
用e返回的e队头元素。
EnQueue(&
Q,e)
插入元素e为Q的新的队尾元素。
DeQueue(&
Q,&
删除Q的队头元素,并用e返回其值。
QueueTraverse(Q,visit())
Q已经存在且非空。
从队头到队尾,依次对Q的每个数据元素调用函数visit()。
一旦visit()失败,则操作失败。
}ADTQueue
2.6模块划分
2.6.1主程序模块
main(){
初始化
while(重复条件){
接受命令;
switch(调用条件)
Case调用条件’A’到达处理;
break;
Case调用条件’D’离开处理;
Case调用条件’E’退出处理;
}
2.6.2两个栈模块
实现栈抽象数据类型:
数据对象:
数据关系:
2.6.3队列模块
实现队列抽象数据类型
R1={ai-1,aiai-1,ai∈D,i=2,……,n}约定中端为队列头,后端为队列尾。
2.6.4模块调用关系
图2-2模块调用关系
栈模块1----模拟停车场
栈模块2----模拟倒车场
队列模块----模拟车道
2.7详细设计与源程序
2.7.1详细设计
以栈模拟停车场,以队列模拟停车场外的便道,按照从终端读入的输入数据序列进行模拟管理。
另设一个栈,临时停放为离去的汽车让路而从停车场退出来的汽车。
栈以顺序存储结构实现,队列以链表存储结构实现。
停车场栈park模拟停车场。
临时栈Aux-park模拟倒车场。
便道队列Road模拟停车场外便道。
程序运行后,先设定停车时间单位和计费单位,再设定停车场容量(测试数据设定停车场容量n=2)。
继续输入车辆数据:
车辆属性(到达’A’或离开’D’)、车牌号、时间(到达时间或离开时间)。
程序根据输入数据中的“车辆属性”进入该属性程序模块。
输出车辆停放位置或离开时的收据。
然后循环,继续输入车辆数据。
当输入车辆数据为’E’时,程序自动退出。
2.7.2部分源程序
停车场问题管理程序代码如下:
#include<
//定义输入/输出函数
iostream.h>
//数据流输入/输出
string.h>
//字符串处理
math.h>
//定义数学函数
stdlib.h>
//定义杂项函数及内存分配函数
#definesize2//停车场位置数
//模拟停车场的堆栈的性质
typedefstructzanlind{
intnumber;
//汽车车号
intar_time;
//汽车到达时间
}zanInode;
typedefstruct{
zanInode*base;
//停车场的堆栈底
zanInode*top;
//停车场的堆栈顶
intstacksize_curren;
}stackhead;
//堆栈的基本操作;
voidinitstack(stackhead&
L)//构造一个空栈
{
L.base=(zanInode*)malloc(size*sizeof(zanlind));
if(!
L.base)exit(0);
//存储分配失败
L.top=L.base;
L.stacksize_curren=0;
voidpush(stackhead&
L,zanInodee)//把元素e压入L栈成为新的栈顶元素
*L.top++=e;
L.stacksize_curren++;
voidpop(stackhead&
L,zanInode&
e)//把元素e弹出L栈
if(L.top==L.base)
cout<
<
"
停车场为空!
!
return;
e=*(--L.top);
L.stacksize_curren--;
//模拟便道的队列的性质
typedefstructduilie{
//汽车到达时间
structduilie*next;
}*queueptr;
Typedefstruct{
queueptrfront;
//便道的队列的队头
queueptrrear;
//便道的队列的队尾
intlength;
}linkqueue;
//队列的基本操作
voidinitqueue(linkqueue&
q)//构造一个空队列
2.8调试过程中的问题及系统测试情况
2.8.1出现的问题
(1)编程过程中忽略头文件的作用,导致漏掉了一个头文件<
以致产生下列错误提示。
错误提示:
errorC2065:
'
malloc'
:
undeclaredidentifier
errorC2065:
exit'
执行cl.exe时出错.
在代码中加上#define〈stdlib.h〉,解决此问题。
(2)没有良好的编程习惯,没有合适的缩进及换行,给程序的调试带来了比较多的困难。
(3)编程过程中比较粗心,一些程序结束的分号和成对出现的大括号忘记写。
2.8.2运行过程
图2-3这是停车场系统的登录界面。
图2-4车辆到达登记信息,为了便于观察,车场内最多可停3辆车,
当停车场内已满时,只登记车牌号,然后进入便道上,即进入队列中。
图2-5分别显示车场内和便道上的车辆信息情况。
图2-6车场内车辆离开时,输入离开时间,然后计算、显示费用,
如果便道上有车,则显示要进入车场内的车牌号码,同时登记时间。
课程设计心得体会
过这次数据结构课程设计,我认识到从课本上学到的知识是远远不够的。
本次设计使我深入的了解了栈与队列的建立、插入、删除和在实际问题下灵活运用它们,另一方面使我对栈和队列的抽象数据类型有了进一步的认识。
例如:
关于停车场问题的,总体来说,这个题目还是比较简单的,主要是运用了栈和队列的一些知识和操作。
也没有用到其他太多的数据结构知识。
程序基本上还是能够运行,结果也正确,能够实现那些基本的车辆到达、离开、收费、遍历显示等主要功能。
但我觉得这个程序还有很多小的地方是可以完善的,比如:
在输入登记车辆到达时间的时候,没有相关的小时、分钟数字的限制范围——(小时0~23,分钟0~60);
这就使程序不那么健壮了,还有,在计算收费时如果离开时间是到了第二天了,这样就可能会导致收费时负的或减少很多。
就是说,还应该算天数,要不就要规定只能当天停,当天开走。
我改了几次改不好,又鉴于程序要求中也没有提及,所以我也就没去该了。
只要能实现主要的功能就好了。
我的收获如下
(1)巩固和加深了对数据结构的理解,提高综合运用本课程所学知识的能力。
(2)培养了我选用参考书,查阅手册及文献资料的能力。
培养独立思考,深入研究,分析问题、解决问题的能力。
(3)通过实际编译系统的分析设计、编程调试,掌握应用软件的分析方法。
(4)通过课程设计,培养了我严肃认真的工作作风,逐步建立正确的生产观念、经济观念和全局观念。
根据我在实习中遇到得问题,我将在以后的学习过程中注意以下几点:
1、认真上好专业实验课,多在实践中锻炼自己。
更让我懂得实践是检验和掌握真理的最好办法。
2、写程序的过程中要考虑周到,严密。
3、在做设计的时候要有信心,有耐心,切勿浮躁。
4、认真的学习课本知识,掌握课本中的知识点,并在此基础上学会灵活运用。
5、在课余时间里多写程序,熟练掌握在调试程序的过程中所遇到的常见错误,以便能节省调试程序的时间。
6、虽然经过努力终于把该系统完成,可是该系统还是不完善,程序中的一些算法还不是很清楚,只不过把简单的功能实现了出来,这些缺憾归根结底都是因为我的C++语言和数据结构的水平还不是很高,还需要经过不懈的努力才能做出比较完善的系统。
这次课程设计让我明白要真正的掌握一门编程语言需要的不仅仅是课本上的东西,还要在实际的编程过程中慢慢的掌握其中的奥妙。
同时我明白了,要成为一名优秀的编程人员所要具备的各种条件(坚实的编程语言基础、熟练的调试程序的技能、重要的是要有耐心、同时细心也是不可缺少的)。
所以为了自己的梦想,在以后的学习过程中,我要不断的充实自己,努力的学习。
通过这次课程设计,对数据结构的特点以及存储表示方式的认识有了明显的提高,同时还对在具体应用中选择合适的数据结构和存储结构的能力有了进一步的提升。
参考文献
[1].吕凤哲,C++语言程序设计(第二版).北京:
电子工业出版社,2005
[2].耿国华等著,数据结构——C语言描述,西安电子科技大学出版社
[3].苏仕华,数据结构课程设计.-北京:
机械工业出版社,2005.5
[4]严蔚敏,吴伟民主编.《数据结构》(C语言版).清华大学出版社.2002
[5]殷人昆等著.《数据结构》(C++版).清华大学出版社.2001
[6]金远平著.《数据结构》(C++描述).清华大学出版社.2005
[7]许卓群等著.《数据结