本数据结构实验教案.docx
《本数据结构实验教案.docx》由会员分享,可在线阅读,更多相关《本数据结构实验教案.docx(53页珍藏版)》请在冰豆网上搜索。
![本数据结构实验教案.docx](https://file1.bdocx.com/fileroot1/2022-11/28/46b2732a-77d8-487e-98c8-987e92b48eee/46b2732a-77d8-487e-98c8-987e92b48eee1.gif)
本数据结构实验教案
数据结构
实验教案
授课教师:
许四平
适用专业:
信息与计算科学
使用班级:
13信计1、2
授课时间:
20XX年秋季
授课学时:
14学时
使用教材:
《数据结构》严蔚敏主编
实验指导书:
数据结构实验指导书,
数理学院编,20XX年版
湖北理工学院数理学院
实验安排表
周次
日期
实验课题
学时
实验报告次数
3
3.23
线性表的顺序存储
2
1
3
3.26
线性表的顺序存储
2
1
5
4.4
单链表
2
1
5
4.9
单链表
2
1
7
4.20
栈、队列
3
1
7
4.23
栈、队列
3
1
8
4.27
树与二叉树
2
1
8
4.29
树与二叉树
2
1
9
5.10
树与二叉树
2
1
9
5.10
树与二叉树
2
1
14
6.9
查找
3
1
14
6.10
查找
3
1
数据结构设计性实验项目
1.线性表的合并:
已知线性表La和Lb的元素按值非递减排列。
归并La和Lb得到新的线性表Lc,Lc的元素也按值非递减排列。
分别采用顺序存储结构和链式结构来实现。
2.线性表的逆置:
设有一个线性表(e0,e1,…,en-2,en-1),请编写一个函数将这个线性表原地逆置,即将线性表内容置换为(en-1,en-2,…,e1,e0)。
线性表中的数据可以为整数、字符或字符串,试分别采用顺序存储结构和链式结构来实现。
3.约瑟夫环的实现:
设有n个人围坐一圈,用整数序列1,2,3,……,n表示顺序围坐在圆桌周围的人,现从某个位置s上的人开始报数,数到m的人出列,接着从出列的下一个人又从1开始重新报数,数到m的人出列,如此下去,直到所有人都出列为此。
试设计确定他们的出列次序序列的程序。
如n=8,m=4,s=1时,设每个人的编号依次为1,2,3,…开始报数,则得到的出列次序为4,8,5,2,1,3,7,6。
检查程序的正确性和健壮性。
(1)采用数组表示作为求解过程中使用的数据结构。
(2)采用单向循环链表作为存储结构模拟整个过程,循环链表可不设头节点,必须注意空表和非空表的界限。
4.数制转换:
利用顺序栈和链栈实现数制转换
5.二叉树的遍历:
分别以顺序存储结构和二叉链表作存储结构,试编写前序、中序、后序及层次顺序遍历二叉树的算法。
6.赫夫曼树与赫夫曼编码:
已知某系统在通信联络中只可能出现8种字符a,b,c,d,e,f,g,h,其概率分别为{0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11},试设计Huffman编码,并计算其平均码长。
(1)初始化:
从键盘读入8个字符,以及它们的权值,建立Huffman树。
(2)编码:
根据建立的Huffman树,求每个字符的Huffman编码。
对给定的待编码字符序列进行编码。
(3)译码:
利用已经建立好的Huffman树,对上面的编码结果译码。
译码的过程是分解电文中的字符串,从根结点出发,按字符’0’和’1’确定找左孩子或右孩子,直至叶结点,便求得该子串相应的字符。
(4)打印 Huffman树。
7.学生成绩管理查询系统:
每个学生的数据信息有准考证号(主关键字)、姓名、语文、英语、数学、和总分等数据项,所有学生的信息构成一个学生成绩表。
假设准考证号的头两位表示地区编号。
请设计一个管理系统达到如下基本要求:
(1)初始化:
建立一个学生成绩表,输入准考证号、姓名、语文、英语、数学,然后计算每个学生的总分,存入相应的数据项;注意:
分析数据对象和它们之间的关系,并以合适的方式进行组织(可选择无序的顺序表、有序的顺序表或索引顺序表来进行存储表示);
(2)查找:
综合应用基本查找算法完成数据的基本查询工作,并输出查询的结果;
(3)输出:
有选择性地输出满足一定条件的数据记录,如输出地区编号为"01",并且总分在550分以上的学生的信息;
(4)计算:
计算在等概率情况下该查找表的平均查找长度。
8.排序:
编制程序让机器随机产生2000个整数,放入一个数组中;对此2000个随机数序列分别用冒泡排序、快速排序、希尔排序和堆排序方法进行排序,并比较它们的运行时间。
注意:
每三、四个同学组成一个小组。
每个实验中的题目,可分别由不同的同学完成。
其它题目可以相互交流,以利于互相提高。
数据结构验证性实验项目
实验一线性表的顺序存储
一、实验目的及要求
1、掌握在TC环境下调试顺序表的基本方法
2、掌握顺序表的基本操作,插入、删除、查找、以及有序顺序表的合并等算法的实现。
二、实验学时
2学时
三、实验任务
1、生成一个顺序表并动态地删除任意元素和在任意位置插入元素。
2、将两个有序表合并成一个有序表。
四、实验重点、难点
1、在顺序表中移动元素。
2、在顺序表中找到正确的插入位置。
五、操作要点
(一)顺序表基本操作的实现
[问题描述]当我们要在顺序表的第i个位置上插入一个元素时,必须先将顺序表中第i个元素之后的所有元素依次后移一个位置,以便腾空一个位置,再把新元素插入到该位置。
若是欲删除第i个元素时,也必须把第i个元素之后的所有元素前移一个位置。
[基本要求]要求生成顺序表时,可以键盘上读取元素,用顺序存储结构实现存储。
[实现提示]要实现基本操作,可用实现的基本操作,也可设计简单的算法实现。
[程序实现]
#include
#include
typedefintDataType;
#definemaxnum20
typedefstruct
{intdata[maxnum];
intlength;
}SeqList;
/*插入函数*/
intinsert(SeqList*L,inti,DataTypex)
/*将新结点x插入到顺序表L第i个位置*/
{intj;
if(i<0||i>(*L).length+1)
{printf("\ni值不合法!
");
return0;
}
if((*L).length>=maxnum-1)
{printf("\n表满不能插入!
");
return0;
}
for(j=(*L).length;j>=i;j--)(*L).data[j+1]=(*L).data[j];
(*L).data[i]=x;
(*L).length++;
return1;
}
/*删除函数*/
intdelete(SeqList*L,inti)
/*从顺序L中删除第i个结点*/
{intj;
if(i<0||i>(*L).length)
{printf("\n删除位置错误!
");
return0;
}
for(j=i+1;j<=(*L).length;j++)
(*L).data[j-1]=(*L).data[j];
(*L).length--;
return1;
}
/*生成顺序表*/
voidcreatlist(SeqList*L)
{intn,i,j;
printf("请输入顺序表L的数据个数:
\n");
scanf("%d",&n);
for(i=0;i{printf("data[%d]=",i);
scanf("%d",&((*L).data[i]));
}
(*L).length=n-1;
printf("\n");
}/*creatlist*/
/*输出顺序表L*/
printout(SeqList*L)
{inti;
for(i=0;i<=(*L).length;i++)
{printf("data[%d]=",i);
printf("%d",(*L).data[i]);
}/*printout*/
printf("\n");
}
main()
{SeqList*L;
charcmd;
inti,t,x;
clrscr();
creatlist(L);
do
{
printf("\ni,I-----插入\n");
printf("d,D-----删除\n");
printf("q,Q-----退出\n");
do
{cmd=getchar();
}while((cmd!
='i')&&(cmd!
='I')&&(cmd!
='d')&&(cmd!
='D')&&(cmd!
='q')&&(cmd!
='Q'));
switch(cmd)
{case'i':
case'I':
printf("\nPleaseinputtheDATA:
");
scanf("%d",&x);
printf("\nWhere?
");
scanf("%d",&i);
insert(L,i,x);
printout(L);
break;
case'd':
case'D':
printf("\nWheretoDelete?
");
scanf("%d",&i);
delete(L,i);
printout(L);
break;
}
}while((cmd!
='q')&&(cmd!
='Q'));
}
(二)有序顺序表的合并
[问题描述]已知顺序表la和lb中的数据元素按非递减有序排列,将la和lb表中的数据元素,合并成为一个新的顺序表lc
[基本要求]lc中的数据元素仍按非递减有序排列,并且不破坏la和lb表
[程序实现]
#include
#include
#defineOK1
#defineERROR0
/*定义ElemType为int或别的自定义类型*/
typedefintElemType;
/*链式存储类型*/
typedefstructLNode
{
ElemTypedata;
structLNode*next;
}LNode,*LinkList;
/*单链表的建立(头插法)*/
voidCreateList_L(LinkList&L,intn)//CreateList_L()function
{//ToCreatreaLinkListLwithHeadNode
inti;
LNode*p;
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;
printf("PleaseinputthedataforLinkListNodes:
\n");
for(i=n;i>0;--i)
{
p=(LinkList)malloc(sizeof(LNode));
scanf("%d",&p->data);//ReverseorderinputingforCreatingaLinkList
p->next=L->next;
L->next=p;
}//endoffor
if(n)printf("SuccesstoCreateaLinkList!
\n");
elseprintf("ANULLLinkListhavebeencreated!
\n");
}//endofCreateList()function
voidMergeList_L(LinkList&La,LinkList&Lb,LinkList&Lc)
{
LinkListpa,pb,pc;
pa=La->next;pb=Lb->next;
Lc=pc=La;
while(pa&&pb)
{
if(pa->data<=pb->data)
{
pc->next=pa;pc=pa;pa=pa->next;
}
else
{
pc->next=pb;pc=pb;pb=pb->next;
}
}
pc->next=pa?
pa:
pb;
free(Lb);
}
voidmain()
{
LinkListLa,Lb,Lc,p;
intn;
printf("请输入La的长度n:
");
scanf("%d",&n);
CreateList_L(La,n);
printf("输出La的内容:
");
p=La->next;
while(p)
{
printf("%d->",p->data);
p=p->next;
}
printf("\n");
printf("请输入Lb的长度n:
");
scanf("%d",&n);
CreateList_L(Lb,n);
printf("输出Lb的内容:
");
p=Lb->next;
while(p)
{
printf("%d->",p->data);
p=p->next;
}
printf("\n");
MergeList_L(La,Lb,Lc);
printf("输出Lc的内容:
");
p=Lc->next;
while(p)
{
printf("%d->",p->data);
p=p->next;
}
printf("\n");
}
六、注意事项
1、删除元素或插入元素表的长度要变化。
2、在合并表中当某一个表到表尾了就不用比较了,直接将另一个表的元素复制到总表去即可。
实验二单链表
一、实验目的及要求
1、掌握用在TC环境下上机调试单链表的基本方法
2、掌握单链表的插入、删除、查找、求表长以及有序单链表的合并算法的实现
3、进一步掌握循环单链表的插入、删除、查找算法的实现
二、实验学时
2学时
三、实验任务
1、在带头结点的单链表h中第i个数据元素之前插入一个数据元素。
2、将两个有序单链表合并成一个有序单链表。
3、生成一个循环单链表。
4、在循环单链表中删除一个节点。
四、实验重点、难点
1、在单链表中寻找到第i-1个结点并用指针p指示。
2、比较两个单链表的节点数据大小。
3、循环单链表中只有一个节点的判断条件。
4、在循环单链表中删除一个节点。
五、操作要点
(一)单链表基本操作的实现
1、实现栈的顺序存储和链式存储。
#include
#include
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
#defineMAXQSIZE100
#defineOK1
#defineERROR0
/*定义SElemType为int或别的自定义类型*/
typedefintSElemType;
/*链式栈的存储类型*/
typedefstructSNode
{
SElemTypedata;
structSNode*next;
}SNode,*LinkStack;
/*取链式栈顶元素*/
intGeTop_L(LinkStacktop,SElemType&e)
{
if(!
top->next)
{
printf("Error!
It'sanemptyLinkStack!
\n");
return(ERROR);
}
else
{
e=top->next->data;
return(OK);
}
}
/*将元素压入链式栈*/
intPush_(LinkStacktop,SElemType&e)
{
SNode*q;
q=(LinkStack)malloc(sizeof(SNode));
q->data=e;
q->next=top->next;
top->next=q;
return(OK);
}
/*将元素弹出链式栈*/
intPop_L(LinkStacktop,SElemType&e)
{
SNode*q;
e=top->next->data;
q=top->next;
top->next=q->next;
free(q);
return(OK);
}
/*定义SElemType为int或别的自定义类型*/
typedefintSElemType;
/*顺序栈的存储类型*/
typedefstruct//definestructureSqStack()
{
SElemType*base;
SElemType*top;
intstacksize;
}SqStack;
/*构造空顺序栈*/
intInitStack(SqStack&S)//InitStack()sub-function
{
S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!
S.base)
{
printf("Allocatespacefailure!
\n");
return(ERROR);
}
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return(OK);
}//InitStack()end
/*取顺序栈顶元素*/
intGetTop(SqStackS,SElemType&e)//GetTop()sub-function
{
if(S.top==S.base)
{
printf("It'saemptySqStack!
\n");//ifemptySqStack
return(ERROR);
}
e=*(S.top-1);
return(OK);
}//GetTop()end
/*将元素压入顺序栈*/
intPush(SqStack&S,SElemTypee)//Push()sub-function
{
*S.top++=e;
return(OK);
}//Push()end
/*将元素弹出顺序栈*/
intPop(SqStack&S,SElemType&e)//Pop()sub-function
{
e=*--S.top;
return(OK);
}//Pop()end
voidmain()
{
inti,j;
SqStacks;
LinkStacks1;
SElemTypee;
InitStack(s);
s1=(LinkStack)malloc(sizeof(SNode));
s1->next=NULL;
printf("顺序栈的元素:
\n");
for(i=1;i<=8;i++)
{
scanf("%d",&e);
Push(s,e);
}
printf("顺序栈出栈:
\n");
for(i=1;i<=8;i++)
{
Pop(s,e);
printf("%d",e);
}
printf("\n");
printf("链式栈的元素:
\n");
for(j=1;j<=8;j++)
{
scanf("%d",&e);
Push_(s1,e);
}
printf("链式栈出栈:
\n");
while(NULL!
=s1->next)
{
Pop_L(s1,e);
printf("%d",e);
}
printf("\n");
}
2、利用顺序栈或链栈实现数制转换。
#include
#include
#defineSTACK_INIT_SIZE100
#defineSTACKINCREMENT10
#defineMAXQSIZE100
#defineOK1
#defineERROR0
/*定义SElemType为int或别的自定义类型*/
typedefintSElemType;
/*顺序栈的存储类型*/
typedefstruct//definestructureSqStack()
{
SElemType*base;
SElemType*top;
intstacksize;
}SqStack;
/*构造空顺序栈*/
intInitStack(SqStack&S)//InitStack()sub-function
{
S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!
S.base)
{
printf("Allocatespacefailure!
\n");
return(ERROR);
}
S.top=S.base;
S.stacksize=STACK_INIT_SIZE;
return(OK);
}//InitStack()end
intStackEmpty(SqStackS)
{
if(S.top==S.base)
returnOK;
else
returnERROR;
}
/*取顺序栈顶元素*/
intGetTop(SqStackS,SElemType&e)//GetTop()sub-function
{
if(S.top==S.base)
{
printf("It'saemptySqStack!
\n");//ifemptySqStack
return(ERROR);
}
e=*(S.top-1);
return(OK);
}//GetTop()end
/*将元素压入顺序栈*/
intPush(SqStack&S,SElemTypee)//Push()sub-function
{
*S.top++=e;
return(OK);
}//Push()end
/*将元素弹出顺序栈*/
intPop(SqStack&S,SElemType&e)//Pop()sub-function
{
e=*--S.top;
return(OK);
}//Pop()end
/*利用顺序栈实现对于输入的任意一个非负十进制整数,输出与其等值的八进制数。
*/
voidConversion()
{
SqStackS;
SElemTypeN,e;
InitStack(S);