数据结构实习报告.docx
《数据结构实习报告.docx》由会员分享,可在线阅读,更多相关《数据结构实习报告.docx(33页珍藏版)》请在冰豆网上搜索。
![数据结构实习报告.docx](https://file1.bdocx.com/fileroot1/2022-12/11/048a1eb8-0ea0-4476-893d-f05d66679390/048a1eb8-0ea0-4476-893d-f05d666793901.gif)
数据结构实习报告
数据结构课程设计报告
*******
*******
班级:
116102
学生学号:
***********
实习题目一
1.需求规格说明书
设停车场是一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。
汽车在停
车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆
车停放在车场的最北端),若车场内已停满n辆汽车,则后来的汽车只能在门外的便道上等
候,一旦有车开走,则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在它
之后进入的车辆必须先退出车场为它让路,待该辆车开出大门外,其他车辆再按原次序进入
车场,每辆停放在车场的车在它离开停车场时必须按它停留的时间长短交纳费用。
试为停车
场编制按上述要求进行管理的模拟程序。
2.总体分析与设计
【设计思想】
在内存中实现,无需外存的流处理过程。
主要的算法思想是栈和队列的使用。
以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理。
每一组输入数据包括三个数据项:
汽车“到达”或“离去”信息,汽车牌照号以及到达或离去的时刻。
对每一组输入的数据进行操作后的输出信息为:
若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车辆离去,则输出汽车在停车场内停留的时间和应交纳的费用(在便道上停留的时间不收费)。
栈以顺序结构实现,队列以链表结构实现。
【设计表示】
【详细设计表示】
主函数开始时要求用户输入停车场的初始大小,然后对进入的车辆进行管理,如果是进入,调用添加函数,此函数中定义的规则是如果停车场如果没有满就加到停车场栈中,如果停车场已经满了,就添加到走道队列中。
处理完添加函数后while循环调用次过程。
同理,如果是车辆要出去,就调用删除函数,如果删除后走道上有车在等待车位就将走道上的车辆根据先进先出的规则压到栈中。
处理完删除函数之后也while循环调用次过程。
只有当用户输入结束的时候此循环才会结束。
3.编码
1.输入A表示的是添加,输入D表示删除,输入E表示结束,那么要是用户不小心输入了其他的一个字母怎么办呢?
在while循环中最开始进行判断的并不是输入的是否为ADE而是输入的是不是不是ADE中间的任何一个,这时候令输入无效,用户需重新输入。
此时的输入作废。
2.添加的时候如果是栈没有满,这时应该添加到栈中去,储存进入时间和车号,但是如果只是停在走道上需不需要这些数据呢?
这里要不要抖没有关系,因为在这里如果要了的话在后面闪出部分走道上的车子重新进入的时候就重新记录一遍车子的进入时间,避免在走道上的时间也要被收费。
3.删除的时候将此时的时间减去车子这个数据对象的进入时间就是时间差,根据规定的单价计算停车费用。
但是如果走道上有车子的时候他的进入时间呢?
处理时一定的,一定要更新,否则车子在走道上的时间也总算在停车场的时间这是不对的。
4.如果在停车场中要出去的车是先进来的车子,则表示比他后来的车要先出去那此时的算法呢?
答案是也将前面的车先存在一个栈中,等向后面的车子先出去后在出栈重新压栈。
4.程序算分分析
【运行结果】
5.小结
【改进设想】
用类的思想,本题我还是沿用的过程思想,对各个过程处理好就出了结果,尽管结果没有错,但是和面向对象的思想不是太符合,所以希望可以用个停车场这一个类来处理问题。
【体会】
有时候在调试的时候的很小的一个结果和预想的不符就是很大的思想问题,比如我调试的时候最后一步有时候钱算的不对,就是添加删除时的时间没有处理正确,所以,错误不在小。
要知道为什么会出这个错。
编程的时候重要的是提前把思路理好。
6.附录
classCar
{
public:
intcarno;//车牌号
intintime;//时间
};
intn;//停车场容量
intno;//车牌号
charsitua;//状态
inttim;//进出站时间
intindex=1;//车的序列
intpreindex=index;//跟踪index
cout<<"输入停车场容量:
";
cin>>n;
cout<Stakecarpark(n);//停车场栈
Staketempstake(8);//临时车站
LinkedQueuepassage;//走道队列
Carcar[7];//车对象6个
/*for(inti=1;i<=6;i++)
{
car[i].carno=i;
}*/
while(true)
{
cout<<"进站还是出站:
";
cin>>situa;
if(situa!
='A'&&situa!
='D'&&situa!
='E')
{
cout<<"错误状态!
请输入A,D或者E!
"<cout<<"进站还是出站:
";
cin>>situa;
}
if(situa=='A')
{
cout<<"车牌号:
";
cin>>no;
cout<<"进/出站时间:
";
cin>>tim;
if(index<=2)
{
cout<<"位置:
"<}
else
{
cout<<"车道上"<}
car[no].intime=tim;
car[no].carno=no;
index++;
//如果栈满就加到队列中
if(carpark.IsFull())
{
passage.Add(no);//
}
//如果栈没有满就压栈
if(!
carpark.IsFull())
{
carpark.Add(no);
}
}
//出车站
if(situa=='D')
{
cout<<"车牌号:
";
cin>>no;
cout<<"进/出站时间:
";
cin>>tim;
cout<<"停留时间:
"<cout<<"应缴费用:
"<<(tim-(car[no].intime))*2<<"元"<index--;
preindex--;
//把no以前的car都放到tempstake里面,再删除no,在放回
intcp_delete;
inttcp_delete;
intpas_delete;
intwaste;
while(carpark.Top()!
=no)
{
carpark.Delete(cp_delete);
tempstake.Add(cp_delete);
}
carpark.Delete(waste);
while(!
tempstake.IsEmpty())
{
tempstake.Delete(tcp_delete);
carpark.Add(tcp_delete);
}
//如果走道有车就加到栈顶
if(!
passage.IsEmpty()&&!
carpark.IsFull())
{
passage.Delete(pas_delete);//1
carpark.Add(pas_delete);
}
cp_delete=0;
tcp_delete=0;
pas_delete=0;
waste=0;
}
if(situa=='E')
{
break;
}
cout<}
cout<<"感谢使用本程序,祝您新年快乐!
"<实习题目二
1.需求规格说明书
人们在日常生活中经常需要查找某个人或某个单位的电话号码,本实验将实现一个简单的个人电话号码查询系统,根据用户输入的信息(例如姓名等)进行快速查询。
2.总体分析与设计
【设计思想】
本题要求的是做一个通讯录,由于所需要的数据量比较大,所以考虑在外存中进行处理,这里用的是txt文件。
当然本来想用数据库的,但是水平不到家。
所以放弃了。
新建一个数据类型,包括姓名,固定电话,移动电话,电子邮箱。
为了实现对电话号码的快速查询,可以将上述结构数组排序,以便应用折半查找,但是,在数组中实现插入和删除操作的代价较高。
如果记录需频繁进行插入或删除操作,可以考虑采用二叉搜索树组织电话号码信息,则查找和维护都能获得较高的时间性能。
【设计表示】
【详细设计表示】
设置四个选项,0、1、2、3分别代表退出、查询、插入、删除。
根据所需要的功能做出操作。
初始数据储存在txt文本中。
如果选择退出则退出系统,如果选择插入则需填写姓名,电话,手机,邮箱信息。
根据名字按照二叉搜索树的形式组织插入,如果选择删除,根据名字的次序在搜索树中删除。
如果是查询也根据二叉搜索树的形式删除。
3.编码
1.名字的判断大小,因为组织二叉搜索树的时候需要对插入和删除做优化,所以需要对名字的大小问题作出比较。
解决的时候是通过操作符重载完成的。
开始的时候不知道汉字怎么比较大小。
后来通过请教了解到汉字可以直接比较大小。
大于号的重载就是这个人的名字大于另外一个人的名字。
2二叉树的插入,我拷的是以前的代码……其实自己重写一遍话的时间还少一些,因为pp和p搞反了。
后来问了张唯老师才在讲的时候发现这个问题。
3.删除的时候在内存中的二叉搜索树中删除很容易但是文本中的内容并没有变,所以在内存中处理完了之后需要重写文本。
开始的时候是先删除所有的文本内容,在重新全部重写。
但是后来发信啊这样内存的开销特别大,而且不容易实现,后来是删除之后直接就在文本中输出。
发现重新输出的时候文本会重新更新。
.4.程序算分分析
【运行结果】
5.小结
【改进设想】
Txt中的信息没有对齐。
如果可以的话用数据库或者excel做可能会清晰一些。
还有就是如果文本中的信息没有8条的话是会出错的。
界面不好。
用mfc会好一些……
【体会】
直接烤以前的代码如果有不适合的话会很麻烦,如果代码不很长的话还是抄一遍吧。
那样会思路清晰一些。
6.附录
ifstreamin("Tele.txt");
//建立流对象
BSTreebstree;
intnum;
inttotal=8;
for(inti=0;i{//把txt里面的信息带出来
in>>Tele[i].name>>Tele[i].mobilnumber>>Tele[i].phonenumber>>Tele[i].email;
};
for(intj=0;j{//做二叉树
bstree.Insert(Tele[j]);
}
while(true)
{
cout<<"***************************"<cout<<"******如果要退出请按0******"<cout<<"******如果要查询请按1******"<cout<<"******如果要插入请按2******"<cout<<"******如果要删除请按3******"<cout<<"***************************"<cin>>num;
if(num==0)
{//退出
break;
}
if(num==1)
{//查找
stringtemp_name;
TelNumbermenber,find_member;
cout<<"您要查找的名字:
";
cin>>temp_name;
bstree.Search(temp_name,find_member);//根据名字找
cout<"<cout<"<cout<"<}
if(num==2)
{//插入完成
ofstreamout("Tele.txt");
TelNumbermem2,insertmen,delmen;
intnum2=0;
cout<<"您插入的人的姓名:
";
cin>>mem2.name;
cout<<"您插入的人的电话:
";
cin>>mem2.phonenumber;
cout<<"您插入的人的手机:
";
cin>>mem2.mobilnumber;
cout<<"您插入的人的邮箱:
";
cin>>mem2.email;
bstree.Insert(mem2);
Tele[total]=mem2;
total++;
while(num2{//重新写txt
if(Tele[num2]!
=mem2)
{
bstree.Delete(Tele[num2],delmen);
out<<}
if(Tele[num2]==mem2)
{
bstree.Delete(Tele[num2],delmen);
out<<}
num2++;
}
for(intj=0;j{
bstree.Insert(Tele[j]);
}
}
if(num==3)
{//删除
stringtemp_name0;
charyorn;
ofstreamout("Tele.txt");
TelNumbermenber0,delete_member;
cout<<"您要删除的名字:
";
cin>>temp_name0;
for(intt=0;t{
if(Tele[t].name==temp_name0)
{
menber0=Tele[t];
}
}
cout<<"您真的要删除吗?
"<while(yorn!
='y'&&yorn!
='n')
{
cout<<"输入y或者n表示yes或者no:
";
cin>>yorn;
}
if(yorn=='y')
{
inttempnum=0;
intnmo=0;
TelNumberhere[100];
while(tempnum{
if(Tele[tempnum]!
=menber0)
{
bstree.Delete(Tele[tempnum],delete_member);
here[nmo]=delete_member;
out<<nmo++;
}
if(Tele[tempnum]==menber0)
{
bstree.Delete(Tele[tempnum],delete_member);
}
tempnum++;
}
//重新插入
for(inte=0;e<=nmo;e++)
{
bstree.Insert(here[e]);
}
total--;
}
cout<<"已删除成功!
"<}
实习题目三
1.需求规格说明书
假定文本文件A1.txt中是我校所有参加南望山庄二期挑房职工的信息,请编写程序,读出文件中的内容,再按挑房的先后次序排队后将排序号和姓名以文本方式存放到文件A2.txt中。
排队原则:
先按职称排,同职称按分房工龄排,同工龄按年龄排。
2.总体分析与设计
【设计思想】
由于测试数据是在文本中的数据,所以处理起来需要用到输入输出流。
将已经给好的a1.txt.中的数据在内存中处理完毕之后就重新输出到另外一个a2.txt中。
【设计表示】
【详细设计】
建立流对象两个,第一个是输入流,一个是输出流。
将给输数据流读到内存中,调用排序函数,这里不能用选择排序,因为选择排序的话要写三个不同的找到最大值函数。
根据三个不同的因素来排。
所以选择冒泡排序。
拍完之后在输出就行了。
3.编码
1.开始的时候建立流对象忘记了。
看以前的数的时候也不知道,因为以前这里也没有学通。
现在做到时候是叫同学叫我怎么做流的技巧的。
2.排序算法。
开始的时候嫌冒泡太麻烦。
要写好多。
想找个简单的但是后来发现就这个用的方便。
其他的都需要重载函数。
太麻烦。
3.调整间距,在用了一个left或right之后只能管一下,在下一个<<操作符之后的地方前面的限定就不起作用了。
需要重新声明左对齐与右对齐。
4.程序算分分析
【运行结果】
5.小结
【体会】
这次实习最大的收获就是学会了初级的输入输出流处理,程序大多数是对输入输出的处理,应付不同的数据组织形式。
需要掌握多种技术。
6.附录
classWorker
{
public:
intnumber;//职称编号
intworkage;//工龄
intage;//年龄
charname[20];//姓名
};
voidbubsort(Workertemp[],intn)
{
inta,b;
Workertempwork;
//根据number排序
for(a=1;a{
for(b=1;b{
if(temp[b].number>temp[b-1].number)
{
tempwork=temp[b];
temp[b]=temp[b-1];
temp[b-1]=tempwork;
}
}
}
//根据工龄排
for(a=1;a{
for(b=1;b{
if((temp[b].number==temp[b-1].number)&&(temp[b].workage>temp[b-1].workage))
{
tempwork=temp[b];
temp[b]=temp[b-1];
temp[b-1]=tempwork;
}
}
}
//根据年龄排
for(a=1;a{
for(b=1;b{
if(temp[b].number==temp[b-1].number&&temp[b].workage==temp[b-1].workage&&temp[b].age>temp[b-1].age)
{
tempwork=temp[b];
temp[b]=temp[b-1];
temp[b-1]=tempwork;
}
}
}
}
intmain(intargc,char*argv[])
{
ifstreamin("123.txt");//定义输入流,源txt
ofstreamout("ok.txt");//定义输出流,目标txt
intwidth=40;
charinformation[40];
in.getline(information,width);//把宽度为width的字符放在info中
out<Workerworker[505];
for(inti=0;i<505;i++)
{
in>>worker[i].name>>worker[i].number>>worker[i].workage>>worker[i].age;
}
bubsort(worker,505);
for(intindex=0;index<505;index++)
{
out<}