实验指导书数据结构与算法 实验完整版.docx

上传人:b****6 文档编号:3313691 上传时间:2022-11-21 格式:DOCX 页数:27 大小:31.42KB
下载 相关 举报
实验指导书数据结构与算法 实验完整版.docx_第1页
第1页 / 共27页
实验指导书数据结构与算法 实验完整版.docx_第2页
第2页 / 共27页
实验指导书数据结构与算法 实验完整版.docx_第3页
第3页 / 共27页
实验指导书数据结构与算法 实验完整版.docx_第4页
第4页 / 共27页
实验指导书数据结构与算法 实验完整版.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

实验指导书数据结构与算法 实验完整版.docx

《实验指导书数据结构与算法 实验完整版.docx》由会员分享,可在线阅读,更多相关《实验指导书数据结构与算法 实验完整版.docx(27页珍藏版)》请在冰豆网上搜索。

实验指导书数据结构与算法 实验完整版.docx

实验指导书数据结构与算法实验完整版

《数据结构与算法》

实验指导书

 

湖南理工学院信息与通信工程学院

信息工程教研室编写

 

适用专业:

信息工程电子信息工程

通信工程自动化

 

信息与通信工程学院

前言

 

本实验指导书是与《数据结构与算法》(C语言版,郭龙源胡虚怀何光明编著,清华大学出版社)一书配套的实验指导书,实验课时为24课时,共安排有12个实验。

实验设置采取先简后繁、先量少后量大、先精叙后粗讲的原则,建议在教授完第3章栈之后即开始实验,实验的安排应与教学进度相配合。

本实验指导书由湖南理工学院信息与通信工程学院信息工程教研室组织编写,其中邓涛老师编写了实验一至四和实验九至十二,李文彬老师编写了实验五至八,严太山老师、齐琦老师和吴岳芬老师分别审订了实验一至四、实验五至八和实验九至十二。

2013年2月

实验项目设置与内容提要

根据各专业培养计划,数据结构与算法课程的实验学时一共安排了24学时。

本课程实验开设12个必修实验(24学时),每个实验都安排有预习内容、课堂实践内容和课后思考内容,要求学生课前学习预习内容,课中完成课堂实践内容,而课后思考内容学生则应根据掌握知识的程度选做。

实验项目设置与内容提要

序号

实验项目

实验学时

每组人数

实验类型

实验要求

内容提要

1

栈的定义

(一)—顺序栈

2

1

综合

必修

1、

2

栈的定义

(二)—链栈

2

1

综合

必修

1、

3

栈的应用——平衡符号

2

1

综合

必修

1、

4

栈的应用——表达式求值

2

1

综合

必修

1、

5

二叉树的定义

2

1

综合

必修

1、

6

二叉树的前序、中序和后序算法

2

1

综合

必修

2、

7

哈夫曼编码算法的实现

2

1

综合

必修

3、

8

哈夫曼解码算法的实现

2

1

综合

必修

4、

9

邻接矩阵图的定义

2

1

综合

必修

5、

10

邻接矩阵图的深度和广度优先遍历

2

1

综合

必修

6、

11

邻接表图的定义

2

1

综合

必修

7、

12

最短路径算法的实现

2

1

综合

必修

8、

实验一栈的定义

(一)

实验学时:

2

实验类型:

综合

实验要求:

必修

一、实验目的

本实验作为课程配套实验的第一个实验,旨在帮助学生进一步理解数据结构—栈,并运用已学习的知识实现一个顺序栈。

与此同时,也对复杂程序的设计过程和常见的开发技巧进行一些介绍。

请同学们在学习完教材相关内容后、在阅读预习内容的同时或之后完成课堂实践内容。

二、预习内容

1、关于抽象数据类型

编写复杂程序或者大型程序是有基本步骤的,如果不按这些步骤来编写,则或者无法按期完成工作,或者完成的工作质量很差。

现在假设我们要编写一本书,例如我们手上的这本《数据结构与算法》教材,那么我们应该怎样来开始我们的工作呢?

一般的写作过程是,首先确定这本书要编入哪些内容,这些内容应分布到哪些章节,这样就可以确定出这本书的目录及各章节的内容,然后再开始编写每一章节。

编写复杂程序的过程与之类似,在第一个阶段则首先需要确定程序的功能,即程序需要完成哪些操作,然后确定程序的输入和输出数据的格式,最后确定解决问题的算法及相应的数据结构。

第二阶段则首先用伪码来实现相应的数据结构和算法,然后再通过逐步求精将伪码转化为对应的代码。

第三阶段则是代码的测试与重构。

下面我们以教材第79页的编程项目2(设计一个算法,判断一个字符串是否是回文(即正向拼写和反向拼写相同))来理解这些过程。

对于这样一个编程任务,它的输入和输出是非常简单的,输入是一个字符串,输出则可以是0或者1。

算法可以首先写成以下形式内容:

(1)将读入的字符逐一入栈

(2)将栈内字符逐一出栈并与原字符串逐一比较

(3)判断——若每个字符都相等则为回文

显然这个算法如果要实现,我们就必须使用栈这样的数据结构,因此在第二阶段我们就需要用伪码来表示栈及相应算法。

栈的伪码首先可以写成像教材第50页的栈抽象数据类型的定义形式,然后再逐步求精。

2、头文件与源文件的分工

在我们拿到一个抽象数据类型的定义后,需要确定应采用编程语言的哪种数据类型来实现这个抽象数据类型。

例如栈,可以用数组来实现即顺序栈,也可以用链表来实现即链栈,本实验将采用顺序栈即使用数组来实现。

在确定数据类型后就可以开始编写数据结构了。

为编写一个数据结构,我们需要编写一个头文件(.h文件)和一个源文件(.C或.CPP文件)。

那么为什么要这样作呢?

在回答这个问题前,我们需要先了解在头文件和源文件中的内容。

在头文件中一般写数据结构的声明、函数原型、#define常数等,但一般来说不写出具体的实现。

并且在写头文件时需要注意,在开头和结尾处必须按照如下样式加上预编译语句:

#ifndefSTACK_H

#defineSTACK_H

//你的代码写在这里

#endif

这样做是为了防止重复包含文件,不这样做就有可能在一个源程序中包含这个头文件两次或更多次时出现重复定义错误,而这样做了就没有问题。

至于源文件则主要是实现头文件中已经声明的那些函数的具体代码。

需要注意的是,开头必须#include一下实现的头文件,以及要用到的其他头文件。

那么当你需要用到自己写的数据结构时,只需要#include相应的头文件就行了(最好把这个头文件存放在指定工程的目录下)。

(参考并完成课堂实践内容1)

在了解了头文件与源文件内容的不同之处之后,再来回答上一个问题:

为什么要把代码分别放到不同的文件中呢?

可不可以只放在一个源文件中呢?

对于第二个问题的回答是:

当然可以。

既然这样,放在两个文件有什么好处呢?

好处是很多的,下面是其中的一种情况。

假如有另外一个程序员希望能使用你编写的栈,那么你可以将头文件和由源文件编译生成的目标文件(.OBJ)文件交给他就OK了。

这样他既可以使用你编写的栈,又不能看到你的源代码(即你编写的栈的内部实现),也无法对其进行改写。

3、工程与文件的关系

下面就开始数据结构—栈的编写。

我们可以在一般的文本编辑工具如记事本软件中来编写,但在集成开发环境VC中编写会更方便。

首先完成整个工程的框架:

(1)在VC中选择File/New,在New向导的Projects选单中选择Win32ConsoleApplication,同时在Projectname中给工程取名,并在Location中为工程选定工程目录,然后选择OK。

(2)在Win32ConsoleApplication-step1of1对话框中选择Anemptyproject,然后选择Finish,并在NewprojectInformation对话框中选择OK。

这样我们就新建了一个空的、控制台应用程序的工程,工程尚未包含任何程序文档。

(3)以新建的方式为工程添加一个头文件stack.h:

在VC中选择Project/AddtoProject/New,在New向导的Files选单中选择C/C++HeaderFile,并勾选AddtoProject,同时为文件取好名字stack,然后选择OK。

(4)以新建的方式为工程添加一个源文件stack.cpp:

在VC中选择Project/AddtoProject/New,在New向导的Files选单中选择C++SourceFile,并勾选AddtoProject,同时为文件取好名字stack,然后选择OK。

这样,我们就为这个工程添加了一个什么内容都没有的头文件和一个源文件。

在这里,我们需要了解,在VC中一个工作区(workspace)可以包含多个工程;一个工程可以包含多个头文件和多个源文件及其他文件,但这些文件中只有一个文件是活动的(当前的),我们只能对活动文件进行编译;一个工程的所有源文件里有且仅有一个main函数。

下面开始编写头文件,在编写头文件和源文件时,很多同学都是从文件的开头向下逐行编写,但有经验的程序员不这样作,他们使用填空的方式来完成整个编写过程。

首先在stack.h中写入以下内容:

/*栈的定义湖南理工学院信息与通信学院张三2013-01-20*/

#ifndefSTACK_H

#defineSTACK_H

//在此处添加代码

#endif

然后在中间添加以下代码:

structNode

{

};

typedefstructNodeSeqStack;

然后在两个大括号之间添加以下代码:

ElemTypedata[MAXSIZE];

inttop;

很显然,这些代码即教材第50页的程序清单3-1中的内容。

4、编译与链接的时机

很多同学在编写代码时,特别是录入书上已有的代码时喜欢一次性将整个代码全部输入完才去编译,这个时候如果程序中有编译错误,则因为代码太多很难确定错误的位置。

因此,有经验的程序员会每编写一小段代码就编译一次,以便能将错误控制在很小的范围内。

本次实验在完成上述工作后,对于初学者来说就应该编译一下以确保输入的内容没有错误。

此时,如果我们选择VC中的Build/Compilestack.h,则会弹出一个对话框提示“cannotcompilethefile……”,即没有程序与头文件的编译相关联,因为头文件是不能编译的。

那么,怎么才能对头文件进行检查呢?

可以将头文件包含进源文件中,而源文件是可以编译的。

双击一下工作区窗口中的stack.cpp文件,此时stack.cpp文件被激活,虽然此文件目前是没有内容的,但是我们仍然可以选择VC中的Build/Compilestack.cpp来编译它。

然后,请在此文件中加入:

#include"stack.h"

请注意这里用的是双引号,而不是尖括号,表示在文件当前处插入工程目录下的stack.h文件,再次选择VC中的Build/Compilestack.cpp进行编译,此时VC将提示多处错误。

原因之一是ElemType尚没有定义,二是MAXSIZE也没定义。

在stack.h文件中加入以下代码:

#defineMAXSIZE200

typedefcharElemType;

然后再编译stack.cpp就没有错误了。

使用ElemType来作中间变量的原因,是方便修改栈的类型,例如我们要定义一个整型栈时,只须将typedefcharElemType;改为typedefintElemType;即可。

同理,要修改栈的大小,也只须修改#defineMAXSIZE200中的数值即可。

下面需要在stack.h文件中声明栈的全部基本操作函数,参考教材第51页的程序清单3-2,在stack.h文件中输入:

voidStackInit(SeqStack*S);(注意此处与教材相比,函数参数改成了指针,这是因为如果使用结构则在函数调用时将是传值调用,会发生结构的复制,影响程序的效率,并将引起运行时错误)

然后双击一下工作区窗口中的stack.cpp文件,将stack.cpp文件激活,再选择VC中的Build/Compilestack.cpp来编译此文件,以确保函数StackInit的声明正确。

依此方法,逐一将栈的抽象数据类型定义中的所有基本操作函数的声明都加入到stack.h中。

其中请注意以下内容:

(1)程序清单3-3中的BOOL是VC所不识别的,应更改为bool;程序清单3-3中的函数名应按栈的抽象数据类型定义改为StackEmpty(注:

在其他函数调用此函数的位置函数名所要作相应改变,主要是在出栈和取栈顶元素操作中);

(2)程序清单3-4中的函数名应按栈的抽象数据类型定义改为Push;

(3)程序清单3-5中的函数名应按栈的抽象数据类型定义改为Pop;

(4)程序清单3-6中的函数名应按栈的抽象数据类型定义改为StackGetTop;

(5)栈清空和求栈长(深)操作函数定义如下:

voidStackClear(SeqStack*S);

intStackLength(SeqStack*S);

完成后的stack.h文件清单如下:

----------------------------------stack.h----------------------------------------

/*栈的定义湖南理工学院信息与通信学院张三2013-01-20*/

#ifndefSTACK_H

#defineSTACK_H

#defineMAXSIZE200

typedefcharElemType;

structNode

{

ElemTypedata[MAXSIZE];

inttop;

};

typedefstructNodeSeqStack;

voidStackInit(SeqStack*S);

boolStackEmpty(SeqStack*S);

voidPush(SeqStack*S,ElemTypex);

ElemTypePop(SeqStack*S);

ElemTypeStackGetTop(SeqStack*S);

voidStackClear(SeqStack*S);

intStackLength(SeqStack*S);

#endif

----------------------------------stack.h----------------------------------------

完成数据结构的声明后,就要开始定义数据结构了,即开始编写stack.cpp了。

有经验的程序员一般会先将stack.h中所有的函数声明都复制到stack.cpp中,然后再将每个函数声明后的分号改为一对大括号然后编译一次,此时将会出现多个编译错误,原因是有不少函数是有返回值的,而现在每个函数还是空的,所以需要在每个有返回值的函数内临时加入一个return语句,一般对于布尔型、整型和字符型的函数都可以加入return1。

所有有返回值的函数都有返回语句后就可以进行编译以确保输入的代码没有语法错误了。

完成所有操作函数的框架后,就可以逐一填入每个函数的代码了,请按程序清单3-2至3-6完成各个函数的定义,其中请注意以下内容:

(1)程序清单3-3中的TRUE和FALSE是VC中没有预先定义的,应改为true和false;

(2)因为入栈操作中调用了printf函数,因此在stack.cpp文件前面还应加入#include

(3)程序清单3-4中if语句内的等号有误,应改为==;程序清单3-4中的exit(0)函数是在stdlib.h头文件中声明的,所以在stack.cpp文件前面还应加入#include

(4)程序清单3-5中首先应加入变量x的声明语句ElemTypex;,同时TRUE应改为true

(5)程序清单3-6中TRUE应改为true;

(6)栈清空操作与初始化操作代码相同;求栈长操作的代码为returnS.top+1;

完成后的stack.cpp文件清单如下:

----------------------------------stack.cpp----------------------------------------

#include

#include

#include"stack.h"

voidStackInit(SeqStack*S)

{

S->top=-1;

}

boolStackEmpty(SeqStack*S)

{

if(S->top==-1)

returntrue;

else

returnfalse;

}

voidPush(SeqStack*S,ElemTypex)

{

if(S->top==MAXSIZE-1)

{

printf("栈已满!

");

exit(0);

}

S->top++;

S->data[S->top]=x;

}

ElemTypePop(SeqStack*S)

{

ElemTypex;

if(StackEmpty(S)==true)

{

printf("栈已空,无法进行出栈操作");

exit(0);

}

else

{

x=S->data[S->top];

S->top--;

returnx;

}

}

ElemTypeStackGetTop(SeqStack*S)

{

if(StackEmpty(S)==true)

{

printf("栈已空,无法进行取栈顶元素操作");

exit(0);

}

else

returnS->data[S->top];

}

voidStackClear(SeqStack*S)

{

S->top=-1;

}

intStackLength(SeqStack*S)

{

returnS->top+1;

}

----------------------------------stack.cpp----------------------------------------

(参考并完成课堂实践内容2)

5、测试数据结构—栈

在完成数据结构的定义后,一般需要使用一下定义好的数据结构,这样可以测试一下前期的工作是否正确,我们以教材第79页的编程项目2来测试。

这里有两种方式来进行这个测试,一种方法是先新建一个控制台工程,然后将stack.h文件和stack.cpp文件复制到这个工程所在的目录,再在VC中选择Project/AddtoProject/Files,在InsertFilesintoProject对话框中指定要加入到工程中的一个或多个文件。

另一种方法是先新建一个控制台工程,然后将stack.h文件和由stack.cpp编译生成的stack.obj文件复制到这个工程所在的目录,再将stack.h文件加入工程;并在工程的链接选项中将目标文件stack.obj导入链接。

以下为第二种方法的过程:

(1)新建一个空的、控制台应用程序的工程;

(2)将stack.h文件复制到这个工程所在的目录;

(3)将上一个工程中由stack.cpp编译生成的stack.obj文件(在上一工程的debug目录下)复制到这个工程所在的目录;

(5)在VC中选择Project/AddtoProject/Files,在InsertFilesintoProject对话框中指定stack.h文件,将其加入此工程;

(6)在VC中选择Project/Settings…菜单,然后选择Link选单,在其中的Object/librarymodules输入框的最后加入一个空格和stack.obj文件名,这样就指示VC所带的链接器在链接时需要扫描stack.obj文件以便找到某些函数的二进制代码。

(7)通过新建的方式向工程加入一个名为main的源文件(一般情况下如果main函数在这个源文件中最好将此源文件命名为main)

(8)在main.cpp文件中输入以下代码

#include

#include

#include"stack.h"

intIsPalindromes(char*str)

{

SeqStackS;

return1;

}

voidmain()

{

}

然后通过选择Build/build***.exe,来编译并链接整个工程,如果没有错误则继续。

(9)继续完成main.cpp文件中的两个函数IsPalindromes和main,其内容请参照教材第306页;(注意:

1、每输入两到三行就编译一下;2、教材第306页代码中某些函数名需作改变以与上一工程中的函数名相同;3、代码中所有栈操作函数的实参数都须改成栈的地址值)4、IsPalindromes中的两处判断栈空的语句都改成了直接调用栈的判空函数来操作,这样作的好处是使得IsPalindromes函数是完全按栈的抽象数据类型定义来操作的,而与栈的内部无关,在下一个实验中同学们将体会到这样改写的好处。

完成后的main.cpp文件如下:

----------------------------------main.cpp----------------------------------------

#include

#include

#include"stack.h"

intIsPalindromes(char*str)

{

SeqStackS;

StackInit(&S);

inti=0;

while(str[i]!

='\0')

{

Push(&S,str[i]);

i++;

}

i=0;

while(!

StackEmpty(&S))

{

if(Pop(&S)!

=str[i])

break;

i++;

}

if(StackEmpty(&S))return1;

elsereturn0;

}

voidmain()

{

char*str;

intn;

printf("请输入字符串的长度:

\n");

scanf("%d",&n);

str=(char*)malloc(n*sizeof(char));

printf("请输入一段字符:

\n");

scanf("%s",str);

if(IsPalindromes(str))

printf("是回文\n");

else

printf("不是回文\n");

}

----------------------------------main.cpp----------------------------------------

工程完成后,选择编译并链接,运行测试结果与教材完全相同。

(参考并完成课堂实践内容3)

三、课堂实践内容

1、请在VC的安装目录下找到math.h文件并阅读之。

(在实验报告中详细标注此头文件的目录)

2、请按实验指导所述步骤逐步添加代码完成顺序栈工程seqstack。

(在实验报告中提交完成的工程)

3、请按实验指导所述步骤逐步添加代码完成顺序栈数据结构的测试工程palindrome(回文数判定)。

(在实验报告中提交完成的工程)

四、实验报告要求

按要求完成课堂实践内容并将问题的回答写入实验报告书,对于编译好的程序请将工程目录下的debug或release目录删除,然后将整个工程目录用winrar软件打包后发到教师邮箱,邮件中用文本文件注明班级学号和姓名。

五、思考题

1、如何改写栈的头文件和源文件才能实现一个浮点数栈?

2、复杂程序的编写应包含哪些过程?

3、头文件中应包含哪些内容?

源文件中应包含哪些内容?

实验二栈的定义

(二)

实验学时:

2

实验类型:

综合

实验要求:

必修

一、实验目的

本实验的主要目的是在上一实验的基础上,继续完成链栈的定义和测试,从而引导学生进一步深入学习栈并了解同一数据结构的不同实现方法。

二、预习

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 其它课程

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1