软件技术基础实验指导书.docx
- 文档编号:9520070
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:79
- 大小:3MB
软件技术基础实验指导书.docx
《软件技术基础实验指导书.docx》由会员分享,可在线阅读,更多相关《软件技术基础实验指导书.docx(79页珍藏版)》请在冰豆网上搜索。
软件技术基础实验指导书
第一章算法
实验一百鸡问题的改进算法
一.实验目的:
掌握列举法、回溯法编程思想。
二.实验内容
利用列举法、回溯法求解百鸡问题,设每只母鸡值3元,每只公鸡值2元,每只小鸡值0.5元。
现要用100元钱买100只鸡,设计买鸡方案。
三.实验原理及算法:
(1)列举法即列举所有可能的情况,并用问题中给定的条件检验哪些是需要的,哪些是不需要的。
改进列举法算法如下:
Forx=0to33
fory=0to50-1.5x
{z=100-x-y;
if3x+2y+z/2=100
thenoutputx,y,z}
nexty
Nextx
(2)对于不能进行无限的列举的问题,一种有效的方法是“试”。
通过对问题的分析,找出一个解决问题的线索;然后沿着这个线索逐步试探。
对于每一步的试探,若试探成功,就得到问题的解;若试探失败,就逐步回退,换别的路线再进行试探。
这种方法就是回溯法。
回溯法解百鸡问题(改进)算法如下:
i:
母鸡数;j:
公鸡数;k:
小鸡数
i=j=0
while(i<33)do
{
If3x+2y+z/2=100
{outputi,j,k;
i=i+1;
j=0
}
else
{
j=j+1;
If(j=50)
{i=i+1;j=0}
}
}
四.实验要求:
编程并实现求解买鸡的方案。
实验二斐波那契数列
一.实验目的:
熟练掌握递归法生成斐波那契数列的编程思想。
二.实验内容:
用递归法生成斐波那契数列{1,1,2,3,5,8,13,21,...},并在屏幕上显示该数列。
三.实验原理:
人们在解决一些复杂问题时,为了降低问题的复杂程度(如问题的规模等),一般总是将问题逐层分解,最后归结为一些最简单的问题。
这种将问题逐层分解的过程,实际上并没有对问题进行求解,而只是当解决了最后那些最简单的问题后,再沿着原来分解的逆过程逐步进行综合,这就是递归思想。
自己调用自己的过程称为递归调用过程。
递归算法是一种很重要的算法设计方法,包含递归关系和递归边界两部分。
四.实验算法:
生成斐波那契数列的算法:
intfbnq(n)
ifn=1orn=2
thenreturn1
elsereturnfbnq(n-1)+fbnq(n-2)
五.实验要求:
编程并运行相应的算法,显示斐波那契数列。
实验三减半递推技术
一.实验目的
熟练掌握减半递推的编程思想。
二.实验内容:
利用减半递推的技术,写出求长度N的数组中最大元素的递归算法,设N=2K,其中K≥1。
三.实验原理:
所谓递推是指从已知的初始条件出发,逐次推出所要求的各中间结果和最后结果。
其中初始条件或是问题本身已经给定,或是通过对问题的分析与化简而得到确定。
递推本质上属于归纳法。
工程上许多递推关系式实际上是通过对实际问题的分析与归纳而得到的,因此递推关系式往往是归纳的结果。
将一般的N阶矩阵相乘转化为低阶矩阵相乘,此类算法设计的方法称为分治法,即对问题分而治之。
工程上常用的分治法是减半递推技术,此技术在快速算法的研究中有很重要的实用价值。
所谓的“减半”是指将问题复杂的规模减半,而问题的性质不变。
所谓的“递推”是指重复“减半”的过程。
四.实验算法:
intMAX(A,I,J)
intA[],I,J
{
intK,M,N;
if(I==J)
returnA[I]
else
{
K=(I+J)/2;
M=MAX(A,I,K);
N=MAX(A,K+1,J)
If(M>N)
Return(M)
Else
Return(N)
}
}
五.实验要求:
编程并实现题目的要求。
实验四八皇后问题
一.实验目的:
熟练掌握递归循环和回溯法的编程思想。
二.实验内容:
由n2个方块排成n行n列的正方形称为“n元棋盘”。
如果两个皇后位于棋盘上的同一行或同一列或同一对角线上,则称它们为互相攻击。
现要求找使n元棋盘上的n个皇后互不攻击的所有布局。
n为8(八皇后问题)即在一个8×8的棋盘里放置8个皇后,要求每个皇后两两之间不相"冲"(在每一横列竖列斜列只有一个皇后)。
三.实验原理:
用递归循环和回溯思想解决八皇后问题,分别一一测试每一种摆法,直到得出正确的答案。
主要解决以下几个问题:
1、冲突。
包括行、列、两条对角线:
(1)列:
规定每一列放一个皇后,不会造成列上的冲突;
(2)行:
当第I行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以I为下标的标记置为被占领状态;
(3)对角线:
对角线有两个方向。
在同一对角线上的所有点(设下标为(i,j)),要么(i+j)是常数,要么(i-j)是常数。
因此,当第I个皇后占领了第J列后,要同时把以(i+j)、(i-j)为下标的标记置为被占领状态。
2、数据结构。
(1)解数组A。
A[I]表示第I个皇后放置的列;范围:
1..8
(2)行冲突标记数组B。
B[I]=0表示第I行空闲;B[I]=1表示第I行被占领;范围:
1..8
(3)对角线冲突标记数组C、D。
C[I-J]=0表示第(I-J)条对角线空闲;C[I-J]=1表示第(I-J)条对角线被占领;范围:
-7..7
D[I+J]=0表示第(I+J)条对角线空闲;D[I+J]=1表示第(I+J)条对角线被占领;范围:
2..16
3.解题步骤
(1)数据初始化。
(2)从n列开始摆放第n个皇后(因为这样便可以符合每一竖列一个皇后的要求),先测试当前位置(n,m)是否等于0(未被占领):
如果是,摆放第n个皇后,并宣布占领(记得要横列竖列斜列一起来哦),接着进行递归;如果不是,测试下一个位置(n,m+1),但是如果当n<=8,m=8时,却发现此时已经无法摆放时,便要进行回溯。
(3)当n>8时,便一一打印出结果。
(4)然后将第n行的皇后右移一个位置,回到步骤
(2),以便寻找下一个布局。
四.实验算法:
产生一次布局的算法。
Procedure try(i);
{for j=1 to 8 do {每个皇后都有8种可能位置}
{
if (b[j]=0) and (c[i+j]=0) and (d[i-j]=0) then {判断位置是否冲突}
{a[i]:
=j; {摆放皇后}
b[j]:
=1; {宣布占领第J行}
c[i+j]:
=1; {占领两个对角线}
d[i-j]:
=1;
if i<8 then try(i+1) {8个皇后没有摆完,递归摆放下一皇后}
else print; {完成任务,打印结果}
b[j]:
=0; {回溯}
c[i+j]:
=0;
d[i-j]:
=0;
}
}
五.实验要求:
编程并实现用递归循环和回溯法求解八皇后问题。
第二章基本数据结构
实验一线性表的操作
一.实验目的:
(1)掌握顺序表的数组表示,插入、删除运算及应用。
(2)掌握单链表的存储结构,链表的建立、插入、删除及应用。
(3)掌握栈和队列的存储结构、操作特点及简单应用。
二.实验原理及意义:
线性表是一种最基本的数据结构,是计算机内部设计操作中必不可少的内容,栈和队列是两种特殊的线性表,它们针对不同的情况和问题,各自有各自的特点。
顺序表用于内存空间较大,要求比较简单,容易理解和设计,但具体处理问题时花费的时间较多;链表是需要数据与指针(即存储地址)结合来实现的,适用于变化情况较多,处理问题方便灵活,但需要额外的空间存储指针,比较浪费空间,好在它对空间的要求是不连续的,不需要大片的连续空间;而栈和队列则在处理函数调用、递归调用,特别是内部处理时是必不可少的,任何一个系统的内部都会用到栈,它本身占用的空间不大,处理的情况、解决的问题都有独特的地方。
通过线性表数据结构的操作与实现,掌握一定的解决问题的能力和方法,针对不同的问题,抽象地分析自己需要的数据结构,在此基础上建立相应的操作和算法,从而更好地为实际服务。
三.实验内容:
1.顺序表操作
在自己的文件夹下,建立一个c语言程序SL.c,完成下列要求:
(1)定义一个长度为10的数组A,即顺序表的形式,并输人数据1,3,4,5,7,9,12,20,28九个数据,然后输出这九个数组元素的存储单元地址和相应的数值;
(2)建立一个数组元素的插入函数,能够按照数据从小到大的次序自动找到插入位置,完成插入元素的操作,调用此函数插入数据15,然后输出数组元素的存储单元地址和相应的数值;
(3)建立一个数组元素的删除函数,能够按照数据自动删除指定元素的操作,调用此函数删除数据值为9的数组元素,然后输出数组元素的存储单元地址和相应的数值。
2.单链表操作
建立第二个C语言程序LL.C,完成下列要求:
(1)定义一个单链表LLIST,按数据1,3,4,5,7,9,12,20,28的次序建立各结点,形成单链表LLIST,按链表顺序输出九个结点的存储单元地址和相应的数据;
(2)建立一个插入函数,将数据15作为结点插入到链表的第五个位置上,完成插入结点的操作,形成新的链表LLIST,然后输出链表结点的存储单元地址和相应的数值;
(3)建立一个删除函数,将链表中的第七个结点删除,形成新的链表LLIST,然后输出链表结点的存储单元地址和相应的数值。
3.栈的操作
建立第三个c语言程序ST.C,完成下列要求:
(1)定义栈的结构LSTACK;
(2)建立入栈函数PUSH()、出栈函数POP()、取栈顶元素函数GETTOP()
(3)解决实用的汉诺(Hanoi)塔问题。
汉诺塔问题可以描述如下:
有三个分别命名为X、Y、Z的塔座,在塔座X上放置若干个直径大小各不相同的圆盘,放置的规则是必须小盘放置在大盘之上。
现在要求利用Y塔座作为中间工具,把所有的圆盘从X塔座移动到Z塔座上,放置的顺序与在X塔座上的次序相同,移动的规则是:
①每次只能移动一个圆盘;
②圆盘可以叠放在任一塔座上;
③任何时候都只能小盘在大盘之上。
实现的过程是当n=1时,简单地把圆盘从X塔座直接移动到Z塔座上,完成只要1步;当n=2时,把X塔座上的小盘先移动到Y塔座上,把X塔座的大盘移动到Z塔座上,然后再把Y塔座上的小盘移动到Z塔座上,完成只要3步;当n=3时,首先把上面的两个盘移动到Y塔座上(小到Z,中到Y,小到Y用3步),把大盘从X塔座移动到Z塔座(大到Z用1步),再把Y塔座上的两个盘移动到Z塔座上(小到X,中到Z,小到Z用3步),完成需要7步;当n进一步增加时,会发现都是重复前面的移动方式,这是一种递归的解决方式。
当n=3时具体操作是:
X、Y、Z是三个栈。
①push(x,3),push(x,2),push(x,1);在X塔座上放置好三个圆盘;
②a=gettop(x),pop(x),push(z,a);取出X栈顶元素a=1并出栈,把a=1人Z栈;
③a=gettop(x),pop(x),push(y,a);取出X栈顶元素a=2并出栈,把a=2人Y栈;
④a=gettop(z),pop(z),push(y,a);取出Z栈顶元素a=1并出栈,把a=1人Y栈;
⑤a=gettop(x),pop(x),push(z,a);取出X栈顶元素a=3并出栈,把a=3入Z栈;
⑥a=gettop(y),pop(y),push(x,a);取出Y栈顶元素a=1并出栈,把a=1人X栈;
⑦a=gettop(y),pop(y),push(z,a);取出Y栈顶元素a=2并出栈,把a=2人Z栈;
⑧a=gettop(x),pop(x),push(z,a);取出X栈顶元素a=1并出栈,把a=1入Z栈。
到此为止已经把X塔座上的三个圆盘移动到了Z塔座上。
如果是四个圆盘,则相当于先把三个圆盘移动到Y塔座上,把最大的放在Z塔座上,再把Y塔座上的三个圆盘移动到Z塔座上,步数是7+1+7=15,依此类推,n个圆盘的移动共需要2n—1步。
4.设计产生一个只有两个结点的链表,第一个结点的数值是A,第二个结点的数值是B,头指针为P。
5.有线性表L=(a1,a2,a3,…,an),设计一个算法,将线性表逆置,即使元素次序变成L’=(an,an-1,…,a2,a1)。
要求不重新开辟空间,用单链表完成。
实验二双向链表原地逆置实验
一.实验目的:
1.熟悉掌握双向链表的生成,遍历及查表。
2.熟悉使用双向链表,理解双向链表的结构类型。
掌握分块查找的原理及设计方法,学会使用C语言实现其对应熟悉使用双向链表,理解双向链表的结构类型及相应的算法。
二.实验内容:
生成一个双向链表,将双向链表中的数据域原地逆置。
三.实验原理:
1.线性链表即线性表的链式存储结构。
在线性单链表中,每一个结点只有一个指针域,由这个指针域能找到后继结点,但不能找到前趋结点,为了找到前趋结点,必须从头指针开始重新寻找。
存储序号数据域指针域
V(i)
NEXT(i)
线性链表的逻辑结构如下:
HEAD
当HEAD=NULL时,成为空表。
2.双向链表:
在单向线性链表的基础上增加了一个指针域,用于指向前趋结点和后继结点。
headrear
before
四.实验算法:
p=head;
q=rear;
while(p≠q&&q.before≠p)
{t=p.d
p.d=q.d
p.d=p.t
p=p.next
q=q.before
}
五.实验要求:
编程并实现该实验内容。
实验三约瑟夫环
一.实验目的:
熟练掌握线性表的基本操作在两种存储结构上的实现。
二.实验内容:
约瑟夫(Joseph)问题的一种描述是:
编号为1,2,…n的n个人按顺时针方向围坐一圈,每人持有—个密码(正整数)。
一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自l开始顺序报数,报到m时停止报数。
报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从l报数,如此下去,直至所有人全部出列为止。
试设计一个程序求出出列顺序。
三.基本要求:
利用单向循环链表存储结构模拟此过程,按照出列的顺序印出各人的编号。
四.测试数据:
m的初值为20;n=7,7个人的密码依次为:
3,l,7,2,4.8,4,首先m值为6(正确的出列顺序应为6,l,4,7,2,3,5)。
五.实现提示:
程序运行后,首先要求用户指定初始报数上限值,然后读取各人的密码此题所用的循环链表中不需要“头结点”,请注意空表和非空表的界限。
六.选作内容:
向上述程序中添加在顺序结构上实现的部分。
#include
#include
typedefstructnode
{
intnum,code;
structnode*next;
}lnode;
voidmain()
{
inti,j,key,n;/*i,j为记数器,key为输入的密码,n为人的总个数*/
lnode*p,*s,*head;
head=(lnode*)malloc(sizeof(lnode));/*为头结点分配空间*/
p=head;
printf("Pleaseenterthenumoftheperson:
");/*输入人的总个数*/
scanf("%d",&n);
for(i=1;i<=n;i++)
{
printf("Person%d",i);
printf("code:
");
scanf("%d",&key);/*输入各个人的密码*/
s=p;
p=(lnode*)malloc(sizeof(lnode));/*创建新的结点*/
s->next=p;
p->num=i;
p->code=key;
}
p->next=head->next;
p=head;
head=head->next;
free(p);
p=head;
do
{
printf("\nPerson%dCode:
%d",p->num,p->code);/*输出链表*/
p=p->next;
}while(p!
=head);
printf("\nPleaseenteryourfirstkey:
");/*输入第一个数*/
scanf("%d",&key);
do
{
j=1;/*j为记数数*/
p=head;
while(j { s=p; p=p->next; j++; } i=p->num; key=p->code; printf("\nTheoutofthenum: "); printf("Person%d",i); s->next=p->next; head=p->next;/*重新定义head,下次循环的开始结点*/ free(p); n--;/*每循环一次人是减1*/ }while(n>0); } 实验四停车场管理 一.实验目的: 深入了解栈和队列的特性,以便在实际问题下灵活运用他们,同时还将巩固对这两种结构的构造方法的理解。 二.实验内容: 设停车场是一个可停放n辆汽车的狭长通道,且只有一个大门可供汽车进出。 汽车在停车场内按车辆到达时间的先后顺序,依次由北向南排列(大门在最南端,最先到达的第一辆车停放在车场的最北端),若车场内已停满n辆汽车,则后来的汽车只能在门外的便道上等候,一旦有车开走,则排在便道上的第一辆车即可开入;当停车场内某辆车要离开时,在它之后进入的车辆必须先退出车场为它让路,待该辆车开出大门外,其他车辆再按原次序进入车场,每辆停放在车场的车在它离开停车场时必须按它停留的时间长短交纳费用。 试为停车场编制按上述要求进行管理的模拟程序。 三.基本要求: 以栈模拟停车场,以队列模拟车场外的便道,按照从终端读入的输入数据序列进行模拟管理。 每一组输入数据包括三个数据项: 汽车“到达”或“离去”信息、汽车牌照号码以及到达或离去的时刻。 对每一组输入数据进行操作后的输出信息为: 若是车辆到达,则输出汽车在停车场内或便道上的停车位置;若是车辆离去,则输出汽车在停车场内停留的时间和应交纳的费用(在便道上停留的时间不收费)。 栈以顺序结构实现,队列以链表结构实现。 四.测试数据: 设n=2,输人数据为: (ˊAˊ,l,5),(ˊAˊ,2,10),(ˊDˊ,l,15),(ˊAˊ,3,20),(ˊAˊ,4,25),(ˊAˊ,5,30),(ˊDˊ,2,35),(ˊDˊ,4,40),(ˊEˊ,O,O)。 其中: ˊAˊ表示到达(Arrival);ˊDˊ表示离去(Departure);ˊEˊ表示输入结束(End)。 五.实现提示: 需另设一个栈,临时停放为给要离去的汽车让路而从停车场退出来的汽车,也用顺序存储结构实现。 输入数据按到达或离去的时刻有序。 栈中每个元素表示一辆汽车,包含两个数据项: 汽车的牌照号码和进入停车场的时刻。 六.选作内容: (1)两个栈共享空间,思考应开辟数组的空间是多少? (2)汽车可有不同种类,则他们的占地面积不同,收费标准也不同,如l辆客车和1.5辆小汽车的占地面积相同,1辆十轮卡车占地面积相当于3辆小汽车的占地面积。 (3)汽车可以直接从便道上开走,此时排在它前面的汽车要先开走让路,然后再依次排到队尾。 (4)停放在便道上的汽车也收费,收费标准比停放在停车场的车低,请思考如何修改结构以满足这种要求。 #include #include #include #defineSize2 #defineprice5 typedefstruct{ charnum[20]; intreachtime; intleavetime; }carinfo; typedefstructstack { carinfocar[5]; inttop; }Stack; typedefstructNode{ carinfodata; structNode*next; }QueueNode; typedefstruct{ QueueNode*front; QueueNode*rear; }Queue,*linkQueue; intEnterQ(Queue*Q,carinfox); intinistack(Stack*S)//初始化栈 { S->top=-1; return1; } voidPush(Stack*S,carinfox)//进栈操作 { S->top++; S->car[S->top]=x; printf("进站成功! "); } voidPop(Stack*S,carinfox)//出栈操作 { if(S->top=-1) printf("空栈,无法出栈! "); x=S->car[S->top]; S->top--; printf("出栈成功! "); } IsEmpty(Stack*S)//判断栈空 { if(S->top==-1) return1; else return0; } intiniQueue(Queue*Q)//初始化便道 { Q->front=(QueueNode*)malloc(sizeof(QueueNode));//申请节点 if(Q->front! =NULL) { Q->rear=Q->front; Q->front->next=NULL; return1; } elsereturn0; } intEnterQ(Queue*Q,carinfox)//进便道 { QueueNode*newNode; newNode=(QueueNode*)malloc(sizeof(QueueNode)); if(newNode! =NULL) { newNode->data=x; newNode->next=NULL; Q->rear->next=newNode; Q->rear=newNode; return1; } elsereturn0; } intDeleteQ(Queue*Q,carinfox)//出便道 { QueueNode*p; p=Q->front->next; if(
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 软件技术 基础 实验 指导书