算法与数据结构C语言描述实验指导书.docx

上传人:b****8 文档编号:24000678 上传时间:2023-05-23 格式:DOCX 页数:27 大小:248.91KB
下载 相关 举报
算法与数据结构C语言描述实验指导书.docx_第1页
第1页 / 共27页
算法与数据结构C语言描述实验指导书.docx_第2页
第2页 / 共27页
算法与数据结构C语言描述实验指导书.docx_第3页
第3页 / 共27页
算法与数据结构C语言描述实验指导书.docx_第4页
第4页 / 共27页
算法与数据结构C语言描述实验指导书.docx_第5页
第5页 / 共27页
点击查看更多>>
下载资源
资源描述

算法与数据结构C语言描述实验指导书.docx

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

算法与数据结构C语言描述实验指导书.docx

算法与数据结构C语言描述实验指导书

 

《数据结构》实验指导书

 

计算机科学与工程学院

 

实验一、熟悉实验环境和单向链表……………………….……………………………..………3

实验二、多项式运算………….………..…………………………………………………………14

实验三、顺序栈的编写…...…………………………………………………………..………….17

实验四、栈的使用—括号匹配…………………..………………………………………………18

实验五、循环队列…………………………………………………..………………….…………19

实验六、二叉排序树…………………………………………………..…………………………20

实验七、图……………………………………………………..………………………………….21

实验八、排序…………………………………………………………..…………………………22

实验九、查找…………………………………………………………..…………………………23

实验一熟悉实验环境和单向链表

一、实验目的

熟悉VC6实验环境

掌握单链表的理论,并能根据需要编写相应的代码

二、实验内容

1、VC6编写控制台c程序指南和代码编写的一些规范

使用VC开发c语言程序,首先要熟悉VC的IDE环境。

IDE(IntegratedDevelopmentEnvironment),即集成开发环境。

编译器厂家将程序编辑器、编译程序、连接程序和调试程序集成在一个开发环境中,使得这个开发环境能完成所有的开发工作,这就是IDE。

当启动VC后,就可以看到它所提供的IDE环境。

如何在VC环境中用c语言编程,开发控制台应用程序。

主要的步骤分为:

1.新建项目

2.添加文件到新建的项目中

3.编写代码

4.编译链接生成可执行文件

其中,代码的调试也是一个很重要的过程。

(一)、新建工程

图1

注意,在图1中一定要选择Win32ConsoleApplication,这样才能编写控制台应用程序。

在图1的中的Projectname下面的文本框填写自己工程的名字,在Location中选择工程要存放的硬盘。

填好后,点击OK,进入下一步。

图2

在图2中,默认选择Anemptyproject,保持默认选项,点击Finish。

就建立了一个空白的控制台工程项目。

以后可以往这个空白的项目中添加现有文件(已经编写好的.c或者.h文件),或者是添加新的空白文件(已经编写好的.c或者.h文件),用于在其上编写自己的代码。

二、往工程中添加文件

应注意,刚选择的是新建一个空白的工程,因此,新建的工程中没有任何.c或者.h文件,现在需要往工程中添加代码文件。

在工程已建立的情况下,有两种方法往工程项目中添加代码,一种是添加空白的.c文件和.h文件,然后自己在这些空白的文件中编写代码,另一种是添加现有的.c文件和.h文件。

若要把添加到工程中的.c或者.h文件从工程中删除,只需要在workspace中选中相应的文件,按下键盘上的delete键,就可以了。

不过,注意,此时文件仅仅是被从工程中移除了,还在硬盘中存在,如果要彻底将文件删除,需要在硬盘上文件保存的地方进行删除。

1.添加空白的.c文件和.h文件

选择File菜单项中的New

(1)添加.c文件的方法如下:

图3

在图3的左边选择C++SourceFile,右边给这个文件取名,这里取名为Demo.c。

需要注意的是后缀一定要为.c,如果不填写,则默认为.cpp类型的文件。

(虽然有人说c是c++的子集,但是,二者还是有些区别的,当编译器把c程序认为是c++程序的话,会有些问题。

)填写后,点击OK按钮。

(2)添加.h文件的方法如下:

图4

图4中,选择C/C++HeaderFile,跟上面一样,可以添加头文件。

2.添加现存的.c文件和.h文件

需要在哪个文件夹下添加文件,直接在那个文件夹上点击右键,如图选择,就可以在随后弹出的对话框中选择相应的文件了。

三、VC的IDE界面的简单介绍

下面简单的介绍一下,VC的IDE界面

图5

如图5所示,VC的IDE界面和传统的Windows程序一样,包含有菜单条、工具条和状态条。

除了这些,主界面共分为三大部分,分别是Workspace窗口、工作区和输出窗口。

其中,Workspace窗口在图5的左半部分,包括FileView页面和ClassView页面,若是编写c程序,只涉及到FileView页面。

在FileView页面中,对加入工程中的文件(包括.h和.c文件)进行了组织,分为3个文件夹,其中,SourceFiles中存放的是.c文件,HeaderFiles中存放的是.h文件,ResourceFiles中存放的是资源文件,而这在现在简单的c程序编写中不会涉及到(若是使用win32API,编写windows程序,会涉及到),因此跟我们相关的只有两个文件夹,SourceFiles文件夹和HeaderFiles文件夹,这两个文件夹对源文件做了很好的组织。

如果你愿意或者说是为了满足编程的需要,也可以在其中新建新的文件夹,管理你的代码文件。

工作区,在窗口的右边,在其中能打开多个代码页面,可以方便的对代码进行编辑修改。

输出窗口在窗口的下部,这个窗口在对程序进行编译链接或者进行调试的时候会出现,显示一些信息。

四、编译链接运行程序

对编写好的程序进行编译链接,可以使用菜单项中的Build菜单,也可以使用工具条中的工具。

Build菜单是VC提供的辅助编程的主要菜单,用于对项目进行编译,连接并生成可执行文件。

其中几个子菜单简单介绍如下:

Compile:

编译当前激活的源文件或头文件

Build:

编译并链接当前激活的项目配置

RebuildAll:

对当前激活的项目配置先Clean,再Build

SetActiveConfiguration:

设置哪个项目配置被激活(其中,默认的是生成Debug版本)

工具条如下:

其中,第一个图标是Compile,第二个图标是Build,第三个是stopbuild,第四个是执行程序(如果新修改好的程序没有编译和链接的话,会有提示,先对程序重新编译链接,再执行),第五个是调试,第六个是设置或移除断点。

五、调试程序

调试程序很重要,有很多方法,比如,可以用printf语句输出中间结果进行调试。

VC6中集成了调试器,可以用vc6的调试器设置断点,进行调试,观察中间结果信息。

主要快捷键的解释如下:

F9:

设置断点

F5:

调试运行

F10:

单步执行,遇到函数不进入函数内部

F11:

单步执行,遇到函数进入函数内部

Shift+F11:

跳出函数

熟练运行快捷键,在调试时会感觉很方便。

在调试过程中会有各种窗口,对中间值进行观察,便于进行程序的调试;同时也会有一个调试的工具栏,如果没有出现调试工具栏,则可以用如下方法调出:

另外,注意一点,最好调试结果是输出窗口中显示的信息中警告也为0个,因为编译器在编译程序的时候,有时检查得不是会很准确的或者说也跟设置的警告的级别有关系,有些警告,在运行的时候就可能会产生问题。

因此,最好是编写的程序在编译链接的时候显示的错误和警告都是0个。

附录:

代码编写的一些规范

1.使用头文件

每个c++/c程序通常分为两个文件。

一个文件用于保存程序的声明(declaration),称为头文件。

另一个用于保存程序的实现(implementation),称为定义(definition)文件。

头文件中只存放“声明”而不存放“定义”。

要学会使用头文件,不要把所有的代码都编写到一个.c文件中,虽然在程序短小的时候,这样做也许也是一个不错的选择,但是,当程序的规模稍微大些的时候,应该学会使用头文件,并且不要把所有的代码都集中到一个.c文件中。

使用头文件的原因或作用如下:

(1)通过头文件来调用库功能。

在很多场合,源代码不便或不准向用户公布,只要向用户提供头文件和二进制的库即可。

用户只需要按照头文件中的接口声明来调用库功能,而不必关心接口怎么实现。

编译器会从库中提取相应的代码。

(2)头文件能加强类型安全检查。

如果某个接口被实现或被使用时,其方式与头文件中的声明不一致,编译器就会指出错误,这一简单的规则能大大减轻程序员调试、改错的负担。

在头文件中,为了防止头文件被重复引用,应当用ifndef/define/endif结构产生预处理块。

用#include格式来引用标准库的头文件(编译器将从标准库目录开始搜索)。

用#include“filename.h”格式来引用非标准库的头文件(编译器将从用户的工作目录开始搜索)。

一个头文件结构的例子如下:

头文件结构(graphics.h)

#ifndefGRAPHICS_H//防止graphics.h被重复引用

#defineGRAPHICS_H//其中GRAPHICS_H为预编译器常量

#include//引用标准库的头文件

#include“myheader.h”//引用非标准库的头文件

voidFunction1(…);//全局函数声明

structBox//结构声明

{

};

#endif

2.程序的版式(可读性)

代码编写出来是给人看的,而不是给机器看的。

编写具有良好的可读性的代码,写上比较好的注释,这样方便自己以后的修改调试,也方便别人的阅读。

有良好的可读性的代码,需要在代码中有适当空行。

代码编写过程中,成对编码原则,也就是说,左右括号是一一对应的,写完左边的括号,最好马上写右边的括号,然后再在两个括号中间填写代码。

另外,内存的分配和释放也都要注意是成对出现的(这里还没有涉及到)。

添加适当的注释,比如函数接口说明,重要的代码段,主要的算法等等。

但是,注释不可以过多。

在VC6中,快速将混乱的代码转换成整齐的代码的方法:

选中需要格式化的代码段,然后按下Alt+F8(或者选择Edit|Advanced|FormatSelection)

3.统一的命名规则

编写程序的时候要注意有一个统一的命名规则。

比如,变量和参数用小写字母开头的单词组合而成;常量全用大写的字母,用下划线分割单词;静态变量加前缀s_(表示static);如果不得已需要全局变量,则使全局变量加前缀g_(表示global)等等。

给函数,变量命名的时候,需要起有意义的名字。

单向链表结点的插入和删除

下面有一个单向链表的部分代码,实现的功能为:

按任意顺序输入几个整数,构造一个排序的线性表,线性表中的元素是降序排列的。

主要函数有3个

插入结点:

通过插入结点的方式构造降序排列的链表

打印链表:

遍历链表中的元素,将其打印出来

删除结点:

根据用户需要删除链表中的结点

其中,插入结点函数,主函数给出,需要补充完整删除结点和打印链表函数,能实现删除链表中结点的功能。

注意:

(1)这里的链式存储结构的线性表中,头结点head也是分配了空间的

(2)如果全部的代码自己能编写出来,更好(自己编写代码的时候,可以给头指针不分配结点空间,仅仅是一个指针)

编写链式存储结构的线性表时候需要注意下面几点:

(1)链表的每个节点都要分配空间

(2)编写单向链表的时候,一定有一个头结点,而因为有这个头指针,根据是否为头指针分配一个实在的结点空间,有两种方法实现后续的链表结点的插入删除遍历等操作。

相对来说,给头指针分配一个实实在在的结点空间(这样这个结点的数据区域会被浪费)的做法利于后续的结点插入和删除操作的实现。

下面为部分代码,可以复制到VC环境中读懂后,编写删除链表结点的函数:

linckList.c

/*

降序链表的插入,删除,打印

*/

#include

#include

structtagNode

{

intdata;

structtagNode*pNext;

};

typedefstructtagNode*pNode;

//将结点插入到链表的适当位置,这是一个降序排列的链表

//

voidinsertList(pNodehead,//链表头结点

pNodepnode)//要插入的结点

{

pNodepPri=head;

while(pPri->pNext!

=NULL)

{

if(pPri->pNext->datadata)

{

pnode->pNext=pPri->pNext;

pPri->pNext=pnode;

break;

}

pPri=pPri->pNext;

}

if(pPri->pNext==NULL)//如果要插入的结点最小

{

pPri->pNext=pnode;

}

}

//输出链表

voidprintLinkedList(pNodehead)

{

pNodetemp=head->pNext;

while(temp!

=NULL)

{

printf("%d",temp->data);

temp=temp->pNext;

}

}

//从链表中删除结点

voiddelformList(pNodehead,intdata)

{

pNodetemp=head->pNext;

pNodepPri=head;

while(temp!

=NULL)

{

if(temp->data==data)

{

pPri->pNext=temp->pNext;

free(temp);

break;

}

pPri=temp;

temp=temp->pNext;

}

}

voidmain()

{

pNodehead=(pNode)malloc(sizeof(structtagNode));//给头指针分配空间

pNodepTemp=NULL;

inttemp;

head->pNext=NULL;//比较好的习惯就是分配好空间,马上赋值

printf("请输入要放入链表中的数据,以-1结尾:

");

//读入数据,以-1结尾,把数据插入链表中

scanf("%d",&temp);

while(temp!

=-1)

{

pTemp=(pNode)malloc(sizeof(structtagNode));

pTemp->data=temp;

pTemp->pNext=NULL;

insertList(head,pTemp);

scanf("%d",&temp);

}

printf("降序排列的链表为:

\n");

printLinkedList(head);

printf("\n");

//下面的代码当删除函数编写成功后,可以取消注释,让其执行,主要是调用函数实现链表结点的删除

//printf("请输入要删除数,以-1结尾:

");

//scanf("%d",&temp);

//while(temp!

=-1)

//{

//delformList(head,temp);

//scanf("%d",&temp);

//}

//printf("删除节点后,链表中剩余数据为:

");

//printLinkedList(head);

//printf("\n");

}

实验二多项式运算

一、实验目的

1、需要从简单的一个文件的C程序中转变过来,知道一个程序的哪些部分要放到.c文件中,哪些部分放到.h文件中,能清晰的组织多个文件进行编译链接,即学会多文件项目的组织

2、初步掌握在VC环境中进行代码的调试

3、掌握一元稀疏多项式的链式存储结构及其加法、减法运算的实现,进一步熟悉链表的插入、删除操作

二、实验内容

问题描述:

设计一个一元稀疏多项式简单的加减法计算器

实现要求:

一元稀疏多项式简单计算器的基本功能是:

(1)输入并建立多项式:

(2)输出多项式

(3)多项式A和B相加,建立多项式C=A+B,并输出相加的结果多项式C

(4)多项式A和B相减,建立多项式C=A-B,并输出相加的结果多项式D

方法说明:

(1)多项式的输入与存储

用带表头结点的单链表存储多项式,链表中的每个节点分别存储多项式各项的系数和指数,即每从键盘输入多项式的一对数(系数,指数),可对应建立链表的一个结点。

每个节点的结构为:

建立两个链表,其中pa和pb分别为它们的头指针:

Pa

pb

结果链表

Pa(或者是Pc)

Pc

(2)多项式数据类型的定义

structtagNode

{

floatcoef;

intexp;

structtagNode*next;

};

typedefstructtagNodeNode;

typedefstructtagNode*pNode;

(3)主要算法

①创建两个链表,分别存放多项式1和多项式2,这两个链表中的节点是按指数降序或者升序排列的

②多项式相加或相减,下面给出多项式相加的部分实现

/*

下面的函数实现两个多项式的相加,要相加的链表分别由pa和pb指向(其中,pa,pb都是分配了空间的头结点)。

相加的结果直接由pa指向的链表保存,即使在pa链表中添加或删除(当系数因为相加为0的情况下)一些结点,构成结果。

这里要相加的链表中指数都是按从小到大的顺序排列好了的,是升序链表。

*/

voidadd_poly(Node*pa,Node*pb)

{

Node*p=pa->pNext;//链表1,将来的结果也放在此

Node*q=pb->pNext;//链表2

Node*pre=pa;

Node*u;//临时用

floatx;

while(p!

=NULL&&q!

=NULL)//当两个链表都不为空

{

if(p->expexp)//比较链表1跟链表2当前节点的指数大小,链表1也是存放结果的地方

{

pre=p;

p=p->pNext;//p指向要比较的下一个结点。

pre指向的是结果链表的最后一个结点。

}

elseif(p->exp==q->exp)//假如链表1和链表2的指数相等,就要系数相加

{

x=p->coef+q->coef;

if(x!

=0)//相加后的系数不为0,有必要保留一个结点就可以了

{

p->coef=x;

pre=p;

}

else//如果相加后,系数不是0,不需要保留任何一个结点,在这里删除链表1的结点,下面删除链表2的结点

{

pre->pNext=p->pNext;//保持链表1的连续性

free(p);

}

p=pre->pNext;//p指向要比较的下一个结点

//下面的代码是进行链表2结点的删除工作,因为指数相等,仅仅需要保留一个结点就可以了

//而结果直接保存在链表1中,所以,删除链表2的结点。

u=q;

q=q->pNext;

free(u);

}

else//如果链表2的当前节点指数小,那么要把链表2的当前节点加入到结果链表中(即是链表1)

{//相当于把结点插入到链表1中,用u作为临时变量,保存链表2的下一个当前节点的位置。

u=q->pNext;

q->pNext=p;

pre->pNext=q;

pre=q;

q=u;

}

}

if(q)//如果链表2比链表1长,那么需要把链表2多余的部分加入结果链表中。

链表1比链表2长,则什么都不用做。

{

pre->pNext=q;

}

free(pb);

}

③输出结果多项式

实验三顺序栈的编写

一、实验目的

掌握顺序栈的编写和实现,并能用自己实现的栈实现相应的算法

二、实验内容

1.自己实现一个顺序栈(栈的成员函数至少必须包括①压栈②出栈③取栈顶元素④判断栈是否为空)

2.编写程序,实现功能为:

输入5个整数,然后将这些整数按与输入时相反的顺序输出。

注意:

(1)栈的结构为

typedefstructtagMyStack

{

intarray[MAX_NUM];//栈

intstackNum;//栈里面的元素个数

}myStack;

(2)程序编写的时候,在参数传递的时候要注意,如果改变了输入参数的值,那么要用指针

实验四栈的使用—括号匹配

一、实验目的

通过一个小程序,掌握和了解栈的使用

二、实验内容

从键盘上输入一算术表达式检验该算术表达式中括号是否配对

提示:

(1)配对的算术表达式中左右括号的数目应相等

例如:

表达式(a+b))和a+b)中的括号不配对

(2)对的算术表达式中每一个括号都一定有一个右括号与之匹配

例如:

表达式)a+b(+c和(b+a))+(c+d也属于不配对的情况

算法提示:

括号配对检查的原则是:

对表达式从左向右扫描。

当遇到左括号时,左括号入栈;而遇到右括号时,首先将栈中的栈顶元素弹出栈,再比较弹出元素是否与右括号匹配,如果两者匹配,则操作继续;否则,检查出错,打印“no”,并停止操作。

当表达式全部扫描完后,如果栈为空,说明括号作用层次嵌套正确,打印“yes”,并停止操作。

方式是先创建一个存放左括号的空栈,并将“#”作为栈底元素。

顺序扫描表达式,当遇到非括号时,继续扫描,遇到“(”时,进栈,而遇到“)”时,与栈等元素比较,如果括号匹配,栈顶元素退栈,继续扫描表达式,否则,报错退出。

这个算法实现中,栈的部分可以直接使用上次实验中自己编写好的栈。

不过,如果使用顺序栈,要明白,顺序栈中的元素个数是有限的。

而且要注意,如果使用的话,需要把栈里面存放数据的类型修改为字符型

实验五循环队列

一、实验目的

掌握循环队列的编写和实现,并能用自己实现的队列实现相应的算法

二、实验内容

1.自己实现一个循环队列(队列的成员函数至少必须包括①进队列②出队列③取队首元素值④判断队列是否为空)

2.编写程序,应用队列实现下述题目描述功能(下面包括题目的描述和说明):

设有两个队列A和B,队列A中按次序存放五个大写字母,分别为A,B,C,D,E;队列B中按次序存放五个小写字母,分别为a,b,c,d,e。

要求每次都从A队列队头取出一个元素,从B队列队头取出一个元素,并列输出这取出的两个元素,直到两个队列为空为止。

使得最后输出为:

AaBbCcDdEe

注意:

(1)队列的结构为

#defineMAX_NUM10

typedefstructtagMyQueue

{

chararray[MAX_NUM];//队列

//这里通过浪费一个空间,来区别队列空还是满

//当front==rear时,队列空

intfront;//约定头指针指示队列头元素的前一个位置,注意这是一个约定,如果你想做别的约定也可以

intrear;//约定尾指针指示队尾元素在队列中的当前位置

}

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

当前位置:首页 > 自然科学 > 物理

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

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