数据结构实验2.docx

上传人:b****5 文档编号:6700940 上传时间:2023-01-09 格式:DOCX 页数:14 大小:28.22KB
下载 相关 举报
数据结构实验2.docx_第1页
第1页 / 共14页
数据结构实验2.docx_第2页
第2页 / 共14页
数据结构实验2.docx_第3页
第3页 / 共14页
数据结构实验2.docx_第4页
第4页 / 共14页
数据结构实验2.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

数据结构实验2.docx

《数据结构实验2.docx》由会员分享,可在线阅读,更多相关《数据结构实验2.docx(14页珍藏版)》请在冰豆网上搜索。

数据结构实验2.docx

数据结构实验2

实验一线性表的运算与应用

实验目的

1、熟悉使用VisualC++编辑、调试、运行程序的步骤和方法。

2、掌握数据结构实验的方法和步骤。

3、掌握线性结构的特点及线性表顺序存储与链式存储两种存储结构的特点。

4、掌握线性表的创建、插入、删除等操作的算法思路和实现方法。

实验内容

预备知识——VisualC++的使用

参阅VisualC++教程,复习VisualC++的使用。

预定义常量和类型

在数据结构实验中,程序中经常会用到像NULL、OK等符号常量,为以后编程方便起见,将这些程序中经常用到的符号常量和类型编写成一个头文件mydefine.h,这样以后编程时需要这些符号常量和类型时,只要将该头文件包含在程序中即可。

头文件mydefine.h的内容如下:

#defineTRUE1

#defineFALSE0

#defineOK1

#defineERROR0

#defineINFEASIBLE-1

#defineOVERFLOW-2

#defineNULL0

typedefintStatus;

实验内容

【问题描述】实现单链表的创建、遍历、插入、删除、查找等基本操作。

【基本要求】

(1)从键盘输入元素的个数n,按逆位序创建一个具有n个元素的带表头结点的单链表。

(2)遍历单链表,依次输出各数据元素的值。

(3)在单链表的第i个位置插入一个值为x的结点,要求从键盘输入要插入的元素值及其插入位置。

(4)在单链表中删除第一个值为x的结点,从键盘输入要删除的结点值x。

(5)从键盘输入一个数x,在单链表中查找第一个值为x的元素在链表中的位置。

(6)编写主函数依次调用上述各算法,进行测试,写出测试过程和结果。

【程序实现】

进入VisualC++编辑环境,输入、调试、运行下面的程序,观察并分析程序的运行结果,回答程序后面的问题。

首先,包含所需的头文件,指定命名空间,定义单链表的存储结构。

#include"mydefine.h"

#include

#include

usingnamespacestd;

//结构定义

typedefcharElemType;

typedefstructLNode//单链表的存储结构定义

{ElemTypedata;

structLNode*next;

}LNode,*Linklist;

其次,依次实现完成创建、插入、删除等各操作的函数。

(1)建立链表是从无到有地建立起一个链表,即一个一个地输入各结点数据,并建立起前后相互链接的关系。

首先建立一个空链表,然后依次生成各结点,新生成结点始终插入在链表的第1个位置(头插法)。

Linklistcreate_L(intn)//逆序创建单链表

{LinklistL,p;inti;

L=newLNode;

L->next=NULL;

cout<<"inputnumbersinlist:

";

for(i=n;i>0;--i)

{p=newLNode;

cin>>p->data;

p->next=L->next;L->next=p;}

return(L);

}

(2)遍历链表是将链表中各结点的数据依次显示。

设一个指针变量p,先指向第1个结点,显示p所指结点的数据,然后p后移一个结点再显示之,直到链表尾结点。

voidprint_L(LinklistL)

{Linklistp;

cout<<"\nThelistis:

\n";

p=L->next;

while(p)

{cout<data;

p=p->next;

}

cout<

}

(3)在单链表的第i个位置插入一个值为x的结点,首先要找到链表中的第i-1个结点,然后生成新结点,将新结点插入到第i-1个结点的后面。

StatusListInsert_L(LinklistL,inti,ElemTypex)

{Linklistp,s;intj;

p=L;j=0;

while(p&&j

{p=p->next;++j;}

if(!

p||j>i-1)returnERROR;//i小于1或大于表长

s=newLNode;//生成新结点

s->data=x;

s->next=p->next;p->next=s;//插入L中

returnOK;

}

(4)删除链表中的结点是从第1个结点开始,检查该结点的数据是否等于要删除的数据,如果相等就将该结点删除,如不相等,则后移一个结点,如此进行下去,直到表尾为止。

voidListDelete_X(LinklistL,ElemTypex)

{Linklistp,q;

p=L;q=p->next;

while(q&&q->data!

=x){p=q;q=q->next;}

if(q){p->next=q->next;free(q);}//删除q所指向的结点

elsecout<

"<

}

(5)在单链表中查找第一个值为x的元素在链表中的位置,只需用一个循环依次扫描表中的每个结点,每扫描一个结点,计数器i加1,记录当前位置,如果当前结点的值等于要查找的值则结束搜索,否则扫描下一个结点。

intLocate_X(LinklistL,ElemTypex)

{inti=0;

Linklistp;

p=L->next;

while(p)

{i++;

if(p->data==x)break;

p=p->next;

}

if(p)returni;

elsereturn0;

}

(6)利用下面的main()函数,测试上述各算法。

voidmain()

{intn,i;

ElemTypex;

LinklistL;

cout<<"inputn:

";

cin>>n;//输入线性表中元素的个数

L=create_L(n);//按逆位序创建线性表

print_L(L);//打印线性表

cout<<"inputi,x:

";//输入要插入的位置i和要插入的数x

cin>>i>>x;

ListInsert_L(L,i,x);//将x插入在L的第i个位置

print_L(L);

cout<<"inputx:

";

cin>>x;//输入要删除的数x

ListDelete_X(&L,x);//在线性表L中删除第一个值为x的结点

print_L(L);//打印删除后的线性表

cout<<"inputx:

";//输入要查找的数x

cin>>x;

i=Locate_X(L,x);//查找x在L中的位置

cout<<"\npositionof"<

}

问题:

(1)写出创建单链表的步骤。

(2)写出程序中实现建立空链表操作的语句。

(3)写出将结点p插入到头结点之后的语句。

(4)分别写出将指针指向链表第一个结点和将指针后移一个结点的语句。

(5)写出在带头结点的单链表L中第i个位置插入值为x的结点的步骤。

(6)写出删除函数ListDelete_X中指针p和指针q所指结点的关系。

 

【选作内容】

(1)从键盘输入元素的个数n,按正位序创建一个具有n个元素的带表头结点的单链表。

(2)建立一个线性链表L,其元素值依次为从键盘输入正整数(以输入一个非正整数为结束);在线性表中值为x的元素前插入一个值为y的数据元素。

若值为x的结点不存在,则将y插在表尾。

(3)在单链表中删除所有值为x的结点,从键盘输入要删除的结点值x。

 

实验二栈和队列及其应用

实验目的

1、深入了解栈和队列的特性。

2、掌握栈和队列基本操作的实现及其应用。

实验内容

【问题描述】用栈和队列来判断一串字符是否为回文。

【基本要求】栈采用顺序栈,队列采用链队。

从键盘读入要测试的字符串。

【实现提示】

1、分析:

(1)判断一串字符是否为回文可以借助一个栈和一个队列来完成,分别定义栈和队列的存储结构及所需要的操作(初始化、入栈/队、出栈/队)。

(2)从键盘逐个读入要测试的字符串的字符(以#结束),每读入一个字符,则将该字符分别入栈和队列。

(3)所有字符读完后,如果栈不空,则每次从栈和队列中各取出一个元素进行比较,如不等则打印不是回文的信息,结束程序,否则继续读数比较,直到栈空,打印是回文的信息。

2、步骤:

(1)编写所需的头文件

◆编写栈实现的头文件:

stack.h

内容包括:

栈的存储结构描述、初始化栈、压栈、弹栈

◆编写队列实现的头文件:

queue.h

内容包括:

队列的存储结构描述、初始化队列、入队、出队

(2)编写源程序实现题目功能,源程序内容如下,试在空白处填上所需内容。

(1)//文件包含命令:

包含预定义常量的头文件mydefine.h

#include

(2)//文件包含命令:

包含栈实现的头文件stack.h

(3)//文件包含命令:

包含队列实现的头文件queue.h

usingnamespacestd;

voidmain()

{chara,b,c;

sqstacks;

linkQueueQ;

(4)//调用队列的初始化函数初始化队列Q

(5)//调用栈的初始化函数初始化栈S

cout<<"inputthestring:

";

cin>>c;

while(c!

='#')

{(6);//将字符c入栈、入队,输入下一个字符

}

while((7))//如果栈不空

{(8);//弹出栈顶元素赋给变量a

(9);//将队头元素出队赋给变量b

if((10))

{cout<<"Thisisn'tacycle.\n";exit(0);}//打印不是回文,并退出程序

}

cout<<"Thisisacycle.\n";

}

 

【选作内容】

利用栈实现数制转换程序。

 

实验三二叉树的存储与遍历

实验目的

1、掌握二叉树的非线性和递归性特点

2、掌握二叉树的存储结构

3、掌握二叉树遍历操作的实现方法

实验内容

【问题描述】建立二叉树的二叉链表表示,实现二叉树的先序、中序、后序和按层次遍历,打印所有叶子结点并统计叶子结点个数。

【基本要求】

(1)采用二叉链表存储结构建立二叉树,从键盘按先序输入二叉树的结点序列。

如,建立如右图所示的二叉树,建立时按先序输入的结点序列为:

abc###de#f##g##,其中“#”表示空格字符,用来代表空树。

(2)二叉树的建立、先序遍历、中序遍历、后序遍历均采用递归方式实现。

(3)编写主函数对各项功能进行测试。

要求分别输出二叉树的先序、中序、后序和按层次遍历的遍历序列,二叉树的所有叶子结点和叶子结点个数。

程序的输入、输出要有相应的提示信息。

【实现提示】

(1)二叉树的二叉链表存储表示:

typedefstructBiTNode

{ chardata;

structBiTNode*lchild,*rchild;

}BiTNode,*BiTree;

(2)二叉树的建立参见教材131页的算法6.4

(3)二叉树的遍历参见教材129页的算法6.1

(4)按层次遍历二叉树需借助队列来实现,把第3章实现的队列的头文件queue.h中的队列数据元素的类型改为BiTree类型,然后将该头文件包含在本程序中,注意该头文件的文件包含命令应写在二叉树存储表示的后面。

算法思路如下:

①初始化一个队列,如果二叉树T非空,则将根结点T进队。

②如果队列非空,则将队头结点出队,打印该结点的数据,然后判断该结点有无左右孩子,如有左孩子,则将左孩子进队,如有右孩子,则将右孩子进队。

③重复执行②,直到队空为止。

【选作内容】

实现二叉树中序遍历的非递归算法。

实验四图的创建和遍历

实验目的

1、掌握图的非线性结构的特点。

2、掌握图的邻接矩阵存储结构及其深度优先搜索操作的实现。

3、掌握图的邻接表存储结构及拓扑排序算法的实现。

实验内容

内容1

【问题描述】采用邻接矩阵存储结构,实现无向图的创建和深度优先搜索程序。

【实现提示】

(1)用邻接矩阵表示图,除了要用一个二维数组存储用于表示顶点间相邻关系的邻接矩阵外,还需用一个一维数组来存储顶点信息,另外还有图的顶点数、边数。

为了反映上面图的全面信息,可以采用以下结构:

#definemax_v20//最大顶点数

typedefstruct

{charvexs[max_v];//顶点向量

intarcs[max_v][max_v];//邻接矩阵

intvexnum,arcnum;//顶点数和边数

}MGraph;

(2)编写创建无向图的函数,程序思路如下:

①输入顶点数和边数。

②输入各顶点信息。

③初始化邻接矩阵。

④输入各条边的信息,建立邻接矩阵。

具体方法可参考下面的程序段:

for(k=0;karcnum;k++)

{cin>>v1>>v2;//输入一条弧的两个邻接点

//在顶点向量中查找两个邻接点的位置

for(i=0;ivexnum;i++)if(G->vexs[i]==v1)break;

for(j=0;jvexnum;j++)if(G->vexs[j]==v2)break;

G->arcs[i][j]=G->arcs[j][i]=1;//邻接矩阵的相应元素置1

}

(3)编写深度优先搜索函数。

为了实现图的遍历需要定义一个全局的标志数组,用以标志一个结点是否被访问过。

定义如下:

intvisited[max_v];

visited数组各元素的初始值均为FALSE,一旦某个顶点被访问过,则将数组相应的分量置为TRUE。

深度优先搜索的过程是一个递归的过程。

算法参见教材169页的算法7.4和算法7.5。

(4)编写主函数进行测试。

首先创建无向图,然后分别输出图的顶点信息和邻接矩阵,最后调用深度优先搜索函数对图进行深度优先搜索遍历,输出遍历序列。

注意程序的输入和输出应有相应的提示信息。

内容2

【问题描述】编写一程序实现图的拓扑排序。

【实现提示】

(1)存储结构定义:

采用邻接表存储结构存储有向图。

定义有向图的邻接表存储表示需先分别定义表结点结构和头结点结构,然后再定义邻接表的存储结构。

同时,为了进行拓扑排序需计算每个顶点的入度,因此需在头结点中增加一个存放顶点入度的数据域。

由此,可采用如下的邻接表存储结构定义:

#defineMAX_VERTEX_NUM20

typedefstructArcNode//表结点结构定义

{intadjvex;//该弧所指向的顶点的位置

structArcNode*nextarc;//指向下一条弧的指针

}ArcNode;

typedefstructVNode//头结点结构定义

{chardata;//顶点信息

intindegree;//顶点的入度

ArcNode*firstarc;//指向第一条依附该顶点的弧的指针

}VNode,AdjList[MAX_VERTEX_NUM];

typedefstruct

{AdjListvertices;//头结点数组

intvexnum,arcnum;//图的当前顶点数和弧数

}ALGraph;

(2)编写创建采用邻接表存储的有向图的函数,程序思路如下:

①输入顶点数和弧数

②输入顶点信息存于头结点数组各元素的data域,头结点数组各元素的入度域indegree置0,指针域firstarc置空;

③输入各条弧,对于每条弧做如下操作:

◆查找弧尾和弧头顶点在头结点数组中的存储位置i和j

◆生成一个新的表结点,其数据域adjvex置为j

◆将新生成的表结点插入第i个链表中

◆头结点数组中的第j个元素的入度indegree的值加1

(3)编写拓扑排序函数。

算法参见教材182页的算法7.12。

(4)编写主函数进行测试。

创建有向图,调用拓扑排序函数对图进行拓扑排序。

 

实验五查找

实验目的

1、掌握顺序查找和二分查找方法的基本思想及其实现技术

2、了解顺序查找和二分查找方法的优缺点和适用范围

实验内容

【问题描述】实现在有n个元素的顺序表上的顺序查找和二分查找。

【基本要求】

(1)编写一个创建函数,建立并输出一个有n个元素的顺序表,数据元素为整型。

顺序表长度和顺序表的各数据元素由键盘输入。

(2)编写函数实现在有n个元素的顺序表上的顺序查找。

(3)编写函数实现在有n个元素的递增有序的顺序表上的二分查找。

(4)提供菜单,供用户选择要执行的操作,根据用户选择调用相应函数实现顺序查找和二分查找。

【实现提示】

程序的实现步骤如下:

(1)顺序表的存储结构定义。

(2)编写创建函数:

由键盘输入顺序表的长度,根据输入的长度分配顺序表的存储空间(注意:

顺序表的0号单元留用,不用来存储顺序表的数据,所以实际分配的存储空间应为顺序表的长度加1),由键盘输入顺序表的各数据元素,存储在顺序表的相应位置,输出顺序表。

(3)编写顺序查找函数,实现在有n个元素的顺序表上的顺序查找。

0号单元用作监视哨。

(4)编写二分查找函数,实现在有n个元素的递增有序顺序表上的二分查找。

(5)编写菜单函数,用于显示输出如下菜单,可通过printf语句在屏幕上打印菜单内容。

*********************

0-exit//退出程序

1-Search_Seq//顺序查找

2-Search_Bin//二分查找

*********************

select:

//选择要执行的操作

(6)编写主函数。

首先显示菜单,用scanf接受用户从键盘输入的操作序号。

然后用switch语句进行判断,根据用户输入执行相应操作。

对于顺序查找和二分查找操作,都应执行如下操作:

●调用创建函数建立顺序表,二分查找时输入的数据应是递增有序的。

●由键盘输入要查找的数,调用相应的查找函数进行查找。

●根据查找函数的返回值输出相应信息:

查找成功输出其位置,查找失败输出数据不存在的信息。

实验六内部排序

实验目的

掌握直接插入排序等排序算法的基本思想及其实现技术。

实验内容

【问题描述】实现直接插入排序和简单选择排序算法。

★选作内容:

实现冒泡排序等其他排序算法。

【基本要求】

(1)设计一个菜单,用户可以通过菜单选择所需的排序算法进行排序。

(2)输入、输出应有相应的提示信息。

【实现提示】

(1)为了简化操作,设待排序的记录只有一个数据项(即待排序的关键字项),待排序的记录采用顺序存储结构存储,存储结构定义可参见如下定义:

#defineMAXSIZE20//顺序表的最大长度

typedefstruct

{intr[MAXSIZE+1];//0号单元留用

intlength;

}SqList;

(2)编写一个函数创建顺序表,由键盘输入待排序的数据个数和待排序的数据。

注意顺序表的0号单元留用,不存储待排序的数据。

(3)编写函数实现直接插入排序,算法参见教材265页算法10.1。

(4)编写函数实现简单选择排序。

(5)编写菜单函数,用于显示输出菜单,可通过printf语句在屏幕上打印菜单内容,每个菜单项给定一个编号(0,1,2,3…)。

(6)编写主函数。

首先显示菜单,用scanf接受用户从键盘输入的操作序号。

然后用switch语句进行判断,根据用户输入执行相应操作。

对于直接插入排序和简单选择排序,都应执行如下操作:

●调用创建函数建立顺序表,输出排序前的顺序表。

●调用相应的排序函数对顺序表中的数据进行排序。

●输出排序后的顺序表。

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

当前位置:首页 > 高等教育 > 管理学

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

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