数据结构实验指导书资料.docx
《数据结构实验指导书资料.docx》由会员分享,可在线阅读,更多相关《数据结构实验指导书资料.docx(35页珍藏版)》请在冰豆网上搜索。
数据结构实验指导书资料
《数据结构》
实验指导书
计算机专业实验中心
2014年9月
目录
《数据结构》上机实验的内容和要求
通过上机实验加深对课程内容的理解,增加感性认识,提高程序设计、开发及调试能力。
序号
实验
名称
内容
提要
每组
人数
实验
时数
实验
要求
实验
类别
分值(总100分)
1
线性表的实现及操作
(一)
顺序表建立、插入、删除等基本操作
1
2
必做
设计
15分
2
线性表的实现及操作
(二)
单链表的建立、插入、删除等基本操作
1
2
必做
设计
15分
3
线性表的应用
约瑟夫环问题或者长整数相加的设计与实现
1
2
选作
综合
10分
4
二叉树的实现及操作
二叉树的基本操作:
树的建立、前序、中序、后序遍历
1
2
必做
设计
20分
5
二叉树的应用
赫夫曼树
1
2
选作
综合
10分
6
图的遍历
图的遍历:
深度优先和广度优先
1
2
必做
设计
20分
7
图的应用
最短路径算法:
Dijkstra算法和Floyd算法
1
2
选作
综合
10分
8
算法性能测试、总结和答疑
对实验课涉及到的算法进行性能测试、对实验所遇到的问题进行总结和答疑
1
2
本实验指导书适用于16学时《数据结构》实验课,实验项目具体内容如下:
其中,第1、2、4、6实验项目为设计性实验,的其内容为程序代码分析与调试,要求每位同学在每次实验课结束前通过检查。
这部分实验应撰写1份实验报告,总分70分。
第3、5、7实验项目为综合应用性实验,学生根据自己的兴趣和基础选作。
这三个实验要求学生利用所学的理论知识解决实际问题,每一个实验应撰写一份实验报告,每个实验10分。
此实验指导书也适用于8学时《数据结构》实验课,要求完成第1、2、4、6实验项目。
实验报告要求
请按照实验教师要求,按时提交实验报告电子版文件。
实验报告格式可个性化定义,内容包括但不限于以下内容:
1、题目、姓名、学号、班级(首页)
2、需求分析:
陈述程序设计的任务,强调程序要做什么,明确规定:
(1)输入的形式和输出值的范围;
(2)输出的形式;
(3)程序所能达到的功能;
(4)测试数据:
包括正确的输入输出结果和错误的输入及输出结果。
3、概要设计:
说明用到的数据结构定义、主程序的流程及各程序模块之间的调用关系。
4、详细设计:
提交带注释的源程序或者用伪代码写出每个操作所涉及的算法。
5、调试分析:
(1)调试过程中所遇到的问题及解决方法;
(2)算法的时空分析;
(3)经验与体会。
6、用户使用说明:
说明如何使用你设计的程序,详细列出每一步操作步骤。
(如果程序操作简单,可略去)
7、测试结果:
列出对于给定的输入所产生的输出结果。
(若有可能,测试随输入规模的增长所用算法的实际运行时间的变化)
8、总结
实验一、线性表的实现及操作
(一)
一、实验目的
了解和掌握线性表的顺序存储结构;掌握用C语言上机调试线性表的基本方法;掌握线性表的基本操作:
插入、删除、查找以及线性表合并等运算在顺序存储结构和链接存储结构上的运算,以及对相应算法的性能分析。
二、实验要求
给定一段程序代码,程序代码所完成的功能为:
(1)建立一个线性表;
(2)依次输入数据元素1,2,3,4,5,6,7,8,9,10;(3)删除数据元素5;(4)依次显示当前线性表中的数据元素。
假设该线性表的数据元素个数在最坏情况下不会超过100个,要求使用顺序表。
程序中有3处错误的地方,有标识,属于逻辑错误,对照书中的代码仔细分析后,要求同学们修改错误的代码,修改后上机调试得到正确的运行结果。
三、程序代码
#include
#defineMaxSize100
typedefintDataType;
typedefstruct
{
DataTypelist[MaxSize];
intsize;
}SeqList;
voidListInitiate(SeqList*L)/*初始化顺序表L*/
{
L->size=0;/*定义初始数据元素个数*/
}
intListLength(SeqListL)/*返回顺序表L的当前数据元素个数*/
{
returnL.size;
}
intListInsert(SeqList*L,inti,DataTypex)
/*在顺序表L的位置i(0≤i≤size)前插入数据元素值x*/
/*插入成功返回1,插入失败返回0*/
{
intj;
if(L->size>=MaxSize)
{
printf("顺序表已满无法插入!
\n");
return0;
}
elseif(i<0||i>L->size)
{
printf("参数i不合法!
\n");
return0;
}
else
{//此段程序有一处错误
for(j=L->size;j>i;j--)L->list[j]=L->list[j];/*为插入做准备*/
L->list[i]=x;/*插入*/
L->size++;/*元素个数加1*/
return1;
}
}
intListDelete(SeqList*L,inti,DataType*x)
/*删除顺序表L中位置i(0≤i≤size-1)的数据元素值并存放到参数x中*/
/*删除成功返回1,删除失败返回0*/
{
intj;
if(L->size<=0)
{
printf("顺序表已空无数据元素可删!
\n");
return0;
}
elseif(i<0||i>L->size-1)
{
printf("参数i不合法");
return0;
}
else
{//此段程序有一处错误
*x=L->list[i];/*保存删除的元素到参数x中*/
for(j=i+1;j<=L->size-1;j++)L->list[j]=L->list[j-1];/*依次前移*/
L->size--;/*数据元素个数减1*/
return1;
}
}
intListGet(SeqListL,inti,DataType*x)
/*取顺序表L中第i个数据元素的值存于x中,成功则返回1,失败返回0*/
{
if(i<0||i>L.size-1)
{
printf("参数i不合法!
\n");
return0;
}
else
{
*x=L.list[i];
return1;
}
}
voidmain(void)
{SeqListmyList;
inti,x;
ListInitiate(&myList);
for(i=0;i<10;i++)
ListInsert(&myList,i,i+1);
ListDelete(&myList,4,&x);
for(i=0;i{
ListGet(,i,&x);//此段程序有一处错误
printf("%d",x);
}
}
实验二、线性表的实现及操作
(二)
一、实验目的
了解和掌握线性表的链式存储结构;掌握用C语言上机调试线性表的基本方法;掌握线性表的基本操作:
插入、删除、查找以及线性表合并等运算在顺序存储结构和链接存储结构上的运算,以及对相应算法的性能分析。
二、实验要求
给定一段程序代码,程序代码所完成的功能为:
(1)建立一个线性表;
(2)依次输入数据元素1,2,3,4,5,6,7,8,9,10;(3)删除数据元素5;(4)依次显示当前线性表中的数据元素。
假设该线性表的数据元素个数在最坏情况下不会超过100个,要求使用单链表。
程序中有3处错误的地方,有标识,属于逻辑错误,对照书中的代码仔细分析后,要求同学们修改错误的代码,上机调试并得到正确的运行结果。
三、程序代码:
#include/*该文件包含pringtf()等函数*/
#include/*该文件包含exit()等函数*/
#include/*该文件包含malloc()等函数*/
typedefintDataType;/*定义DataType为int*/
typedefstructNode
{
DataTypedata;
structNode*next;
}SLNode;
voidListInitiate(SLNode**head)/*初始化*/
{
/*如果有内存空间,申请头结点空间并使头指针head指向头结点*/
if((*head=(SLNode*)malloc(sizeof(SLNode)))==NULL)exit
(1);
(*head)->next=NULL;/*置链尾标记NULL*/
}
intListLength(SLNode*head)
{
SLNode*p=head;/*p指向首元结点*/
intsize=0;/*size初始为0*/
while(p->next!
=NULL)/*循环计数*/
{
p=p->next;
size++;
}
returnsize;
}
intListInsert(SLNode*head,inti,DataTypex)
/*在带头结点的单链表head的数据元素ai(0≤i≤size)结点前*/
/*插入一个存放数据元素x的结点*/
{
SLNode*p,*q;
intj;
p=head;/*p指向首元结点*/
j=-1;/*j初始为-1*/
while(p->next!
=NULL&&j/*最终让指针p指向数据元素ai-1结点*/
{
p=p->next;
j++;
}
if(j!
=i-1)
{
printf("插入位置参数错!
");
return0;
}
/*生成新结点由指针q指示*/
if((q=(SLNode*)malloc(sizeof(SLNode)))==NULL)exit
(1);
q->data=x;
//此段程序有一处错误
p->next=q->next;/*给指针q->next赋值*/
p->next=q;/*给指针p->next重新赋值*/
return1;
}
intListDelete(SLNode*head,inti,DataType*x)
/*删除带头结点的单链表head的数据元素ai(0≤i≤size-1)结点*/
/*删除结点的数据元素域值由x带回。
删除成功时返回1;失败返回0*/
{
SLNode*p,*s;
intj;
p=head;/*p指向首元结点*/
j=-1;/*j初始为-1*/
while(p->next!
=NULL&&p->next->next!
=NULL&&j/*最终让指针p指向数据元素ai-1结点*/
{
p=p->next;
j++;
}
if(j!
=i-1)
{
printf("插入位置参数错!
");
return0;
}
//此段程序有一处错误
s=p->next;/*指针s指向数据元素ai结点*/
*x=s->data;/*把指针s所指结点的数据元素域值赋予x*/
p->next=s->next;/*把数据元素ai结点从单链表中删除指*/
free(s);/*释放指针s所指结点的内存空间*/
return1;
}
intListGet(SLNode*head,inti,DataType*x)
/*取数据元素ai和删除函数类同,只是不删除数据元素ai结点*/
{
SLNode*p;
intj;
p=head;
j=-1;
while(p->next!
=NULL&&j
{
p=p->next;j++;
}
if(j!
=i)
{
printf("取元素位置参数错!
");
return0;
}
//此段程序有一处错误
*x=p->next;
return1;
}
voidDestroy(SLNode**head)
{
SLNode*p,*p1;
p=*head;
while(p!
=NULL)
{
p1=p;
p=p->next;
free(p1);
}
*head=NULL;
}
voidmain(void)
{
SLNode*head;
inti,x;
ListInitiate(&head);/*初始化*/
for(i=0;i<10;i++)
{
if(ListInsert(head,i,i+1)==0)/*插入10个数据元素*/
{
printf("错误!
\n");
return;
}
}
if(ListDelete(head,4,&x)==0)/*删除数据元素5*/
{
printf("错误!
\n");
return;
}
for(i=0;i{
if(ListGet(head,i,&x)==0)/*取元素*/
{
printf("错误!
\n");
return;
}
elseprintf("%d",x);/*显示数据元素*/
}
Destroy(&head);
}
实验三、线性表的应用
一、实验目的
加深对线性表各项操作实现的理解,增强学生问题模拟、数据抽象的能力。
二、实验要求
本实验共有两个题目,作为实验一和实验二的拓展题目,可选作其中一个或者两个都做。
选取根据题目要求进行设计,并编程实现,在实验报告中给出测试数据。
三、实验内容
1、约瑟夫环问题的设计与实现
据说著名犹太历史学家Josephus有过以下的故事:
在罗马人占领乔塔帕特后,39个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。
然而Josephus和他的朋友并不想遵从。
首先从一个人开始,越过k-2个人(因为第一个人已经被越过),并杀掉第k个人。
接着,再越过k-1个人,并杀掉第k个人。
这个过程沿着圆圈一直进行,直到最终只剩下一个人留下,这个人就可以继续活着。
问题是,给定了和,一开始要站在什么地方才能避免被处决?
Josephus要他的朋友先假装遵从,他将朋友与自己安排在第16个与第31个位置,于是逃过了这场死亡游戏。
问题:
假设41个人围成一圈,其中有m个你的朋友不想死掉,从第一个开始报数,第3个将被杀掉。
为了保护自己和m个朋友,现在编写程序,求出如何安排自己和m个朋友的初始位置。
2、长整数表示与相加
很长整数是指无法用long型数存储的数,因此需要用字符串数组来存储两个被加数,相加的结果也保存于字符数组中,假如被加数长度不超过十进制40位,请编程实现该加法程序并将相加结果输出。
四、实验报告要求
1、基本要求见第3页。
2、给出实验结果。
3、对算法的性能进行测试。
要求分析算法的复杂度,测试程序对于不同大小输入的运行情况(例如约瑟夫环,改变人数个数为50,100,1000等,测试其是否正常运行,比较运行时间等)。
实验四、二叉树的实现及操作
一、实验目的
掌握二叉树的定义、结构特征,以及各种存储结构的特点及使用范围,各种遍历算法。
掌握用指针类型描述、访问和处理二叉树的运算。
二、实验内容及要求
有如下二叉树:
程序代码给出了该二叉树的链式存储结构的建立、前序、中序、后序遍历的算法,同时也给出了查询“E”是否在二叉树里的代码。
代码有四处错误,有标识,属于逻辑错误,对照书中的代码仔细分析后,请修改了在电脑里运行,该实验无需写实验报告,程序能完全执行得满分。
改对一处得总分的四分之一。
#include
#include
typedefcharDataType;
typedefstructNode
{
DataTypedata;/*数据域*/
structNode*leftChild;/*左子树指针*/
structNode*rightChild;/*右子树指针*/
}BiTreeNode;/*结点的结构体定义*/
/*初始化创建二叉树的头结点*/
voidInitiate(BiTreeNode**root)
{
*root=(BiTreeNode*)malloc(sizeof(BiTreeNode));
(*root)->leftChild=NULL;
(*root)->rightChild=NULL;
}
voidDestroy(BiTreeNode**root)
{
if((*root)!
=NULL&&(*root)->leftChild!
=NULL)
Destroy(&(*root)->leftChild);
if((*root)!
=NULL&&(*root)->rightChild!
=NULL)
Destroy(&(*root)->rightChild);
free(*root);
}
/*若当前结点curr非空,在curr的左子树插入元素值为x的新结点*/
/*原curr所指结点的左子树成为新插入结点的左子树*/
/*若插入成功返回新插入结点的指针,否则返回空指针*/
BiTreeNode*InsertLeftNode(BiTreeNode*curr,DataTypex)
{
BiTreeNode*s,*t;
if(curr==NULL)returnNULL;
t=curr->leftChild;/*保存原curr所指结点的左子树指针*/
s=(BiTreeNode*)malloc(sizeof(BiTreeNode));
s->data=x;
s->leftChild=t;/*新插入结点的左子树为原curr的左子树*/
s->rightChild=NULL;
curr->leftChild=s;/*新结点成为curr的左子树*/
returncurr->leftChild;/*返回新插入结点的指针*/
}
/*若当前结点curr非空,在curr的右子树插入元素值为x的新结点*/
/*原curr所指结点的右子树成为新插入结点的右子树*/
/*若插入成功返回新插入结点的指针,否则返回空指针*/
BiTreeNode*InsertRightNode(BiTreeNode*curr,DataTypex)
{
BiTreeNode*s,*t;
if(curr==NULL)returnNULL;
t=curr->rightChild;/*保存原curr所指结点的右子树指针*/
s=(BiTreeNode*)malloc(sizeof(BiTreeNode));
s->data=x;
s->rightChild=t;/*新插入结点的右子树为原curr的右子树*/
s->leftChild=NULL;
curr->rightChild=s;/*新结点成为curr的右子树*/
returncurr->rightChild;/*返回新插入结点的指针*/
}
voidPreOrder(BiTreeNode*t,voidvisit(DataTypeitem))
//使用visit(item)函数前序遍历二叉树t
{
if(t!
=NULL)
{//此小段有一处错误
visit(t->data);
PreOrder(t->rightChild,visit);
PreOrder(t->leftChild,visit);
}
}
voidInOrder(BiTreeNode*t,voidvisit(DataTypeitem))
//使用visit(item)函数中序遍历二叉树t
{
if(t!
=NULL)
{//此小段有一处错误
InOrder(t->leftChild,visit);
InOrder(t->rightChild,visit);
visit(t->data);
}
}
voidPostOrder(BiTreeNode*t,voidvisit(DataTypeitem))
//使用visit(item)函数后序遍历二叉树t
{
if(t!
=NULL)
{//此小段有一处错误
visit(t->data);
PostOrder(t->leftChild,visit);
PostOrder(t->rightChild,visit);
}
}
voidVisit(DataTypeitem)
{
printf("%c",item);
}
BiTreeNode*Search(BiTreeNode*root,DataTypex)//需找元素x是否在二叉树中
{
BiTreeNode*find=NULL;
if(root!
=NULL)
{
if(root->data==x)
find=root;