数据结构实验报告动态查找表.docx
- 文档编号:23349926
- 上传时间:2023-05-16
- 格式:DOCX
- 页数:19
- 大小:196.31KB
数据结构实验报告动态查找表.docx
《数据结构实验报告动态查找表.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告动态查找表.docx(19页珍藏版)》请在冰豆网上搜索。
数据结构实验报告动态查找表
数据结构实验报告
题目:
动态查找表
学院计算机学院
专业计算机科学与技术
年级班别2010级计科4班
学号3110006015
学生姓名张法光
指导教师张巍
成绩____________________
2012年6月
1.题目
动态查找表的设计与实现
实现下列操作:
构造空表、销毁表、查找关键字的元素、插入新元素、删除指定关键字的元素、遍历表中所有元素.
抽象数据类型定义:
ADTDynamicSearchTable
{
数据对象D:
D是具有相同特性的数据元素的集合。
各个数据元素均含有类型相同,可唯一标识数据元素的关键字
数据关系R:
数据元素同属一个集合。
基本操作P:
InitDSTable(&DT);
操作结果:
构造一个空的动态查找表DT。
DestroyDSTable(&DT)
初始条件:
动态查找表DT存在。
操作结果:
销毁动态查找表DT。
SearchDSTable(DT,key);
初始条件:
动态查找表DT存在,key为和关键字类型相同的给定值。
操作结果:
若DT中存在其关键字等于key的数据元素,则函数值为该元素的值或在表中的位置,否则为“空”。
InsertDSTable(&DT,e);
初始条件:
动态查找表DT存在,e为待插入的数据元素。
操作结果:
若DT中不存在其关键字等于e.key的数据元素,则插入e到DT。
DeleteDSTable(&DT,key);
初始条件:
动态查找表DT存在,key为和关键字类型相同的给定值。
操作结果:
若DT中存在其关键字等于key的数据元素,则删除之。
TraverseDSTable(DT,visit());
初始条件:
动态查找表DT存在,visit是对结点操作的应用函数。
操作结果:
按某种次序对DT的每个结点调用函数visit()一次且至多一次,一旦visit()失败,则操作失败。
}ADTDynamicSearchTable
2.存储结构定义:
公用头文件DS0.h和宏定义:
#include
#include
#defineTRUE1/*TRUE函数值为1*/
#defineFALSE0
#defineN10/*数据元素个数*/
typedefintStatus;/*Status为函数类型*/
typedefintKeyType;/*关键字域为整型*/
#defineEQ(a,b)((a)==(b))/*定义等于*/
#defineLT(a,b)((a)<(b))/*定义小于*/
二叉排序树存储结构:
二叉排序树的类型BiTree定义如下:
typedefintKeyType;/*关键字域为整型*/
typedefstruct
{
KeyTypekey;
intothers;
}ElemType;/*数据元素类型*/
typedefElemTypeTElemType;
typedefstructBiTNode
{
TElemTypedata;
structBiTNode*lchild,*rchild;/*左右孩子指针*/
}BiTNode,*BiTree;
3.算法设计
/*操作结果:
构造一个空的动态查找表DT*/
StatusInitDSTable(BiTree*DT)
{
*DT=NULL;
returnTRUE;
}
/*初始条件:
动态查找表DT存在。
操作结果:
销毁动态查找表DT*/
voidDestroyDSTable(BiTree*DT)
{
if(*DT){
if((*DT)->lchild)
DestroyDSTable(&(*DT)->lchild);/*销毁左孩子子树*/
if((*DT)->rchild)
DestroyDSTable(&(*DT)->rchild);/*销毁右孩子子树*/
free(*DT);
*DT=NULL;}
}
/*在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元素,*/
/*若查找成功,则返回指向该数据元素结点的指针,否则返回空指针。
*/
BiTreeSearchBST(BiTreeT,KeyTypekey)
{
if((!
T)||EQ(key,T->data.key))
returnT;/*查找结束*/
elseifLT(key,T->data.key)/*在左子树中继续查找*/
returnSearchBST(T->lchild,key);
else
returnSearchBST(T->rchild,key);/*在右子树中继续查找*/
}
/*在根指针T所指二叉排序树中递归地查找其关键字等于key的数据元素,若查找*/
/*成功,则指针p指向该数据元素结点,并返回TRUE,否则指针p指向查找路径上*/
/*访问的最后一个结点并返回FALSE,指针f指向T的双亲,其初始调用值为NULL*/
voidSearchBST1(BiTree*T,KeyTypekey,BiTreef,BiTree*p,Status*flag)
{
if(!
*T)/*查找不成功*/
{
*p=f;
*flag=FALSE;
}
elseifEQ(key,(*T)->data.key)/*查找成功*/
{
*p=*T;
*flag=TRUE;
}
elseifLT(key,(*T)->data.key)
SearchBST1(&(*T)->lchild,key,*T,p,flag);/*递归调用-继续在左子树查找*/
else
SearchBST1(&(*T)->rchild,key,*T,p,flag);/*递归调用-继续在右子树查找*/
}
/*当二叉排序树T中不存在关键字等于e.key的数据元素时,插入e并返回TRUE,*/
/*否则返回FALSE。
*/
StatusInsertBST(BiTree*T,ElemTypee)
{
BiTreep,s;
Statusflag;
SearchBST1(T,e.key,NULL,&p,&flag);
if(!
flag)/*查找不成功*/
{
s=(BiTree)malloc(sizeof(BiTNode));
s->data=e;
s->lchild=s->rchild=NULL;
if(!
p)
*T=s;/*被插结点*s为新的根结点*/
elseifLT(e.key,p->data.key)
p->lchild=s;/*被插结点*s为左孩子*/
else
p->rchild=s;/*被插结点*s为右孩子*/
returnTRUE;
}
else
returnFALSE;/*树中已有关键字相同的结点,无需插入*/
}
/*从二叉排序树中删除结点p,并重接它的左或右子树。
*/
voidDelete(BiTree*p)
{
BiTreeq,s;
if(!
(*p)->rchild)/*右子树空则只需重接它的左子树*/
{
q=*p;
*p=(*p)->lchild;
free(q);
}
elseif(!
(*p)->lchild)/*只需重接它的右子树*/
{
q=*p;
*p=(*p)->rchild;
free(q);
}
else/*左右子树均不空*/
{
q=*p;
s=(*p)->lchild;
while(s->rchild)/*转左*/
{
q=s;
s=s->rchild;
}
(*p)->data=s->data;/*s指向被删结点的"前驱"*/
if(q!
=*p)
q->rchild=s->lchild;/*重接*q的右子树*/
else
q->lchild=s->lchild;/*重接*q的左子树*/
free(s);
}
}
/*若二叉排序树T中存在关键字等于key的数据元素时,则删除该数据元素结点,*/
/*并返回TRUE;否则返回FALSE。
*/
StatusDeleteBST(BiTree*T,KeyTypekey)
{
if(!
*T)/*不存在关键字等于key的数据元素*/
returnFALSE;
else
{
ifEQ(key,(*T)->data.key)/*找到关键字等于key的数据元素*/
Delete(T);
elseifLT(key,(*T)->data.key)
DeleteBST(&(*T)->lchild,key);
else
DeleteBST(&(*T)->rchild,key);
returnTRUE;
}
}
/*初始条件:
动态查找表DT存在,Visit是对结点操作的应用函数*/
/*操作结果:
按关键字的顺序对DT的每个结点调用函数Visit()一次且至多一次*/
voidTraverseDSTable(BiTreeDT,void(*Visit)(ElemType))
{
if(DT)
{
TraverseDSTable(DT->lchild,Visit);/*先中序遍历左子树*/
Visit(DT->data);/*再访问根结点*/
TraverseDSTable(DT->rchild,Visit);/*最后中序遍历右子树*/
}
}
4.测试
voidprint(ElemTypec)/*以下主函数调用*/
{
printf("(%d,%d)",c.key,c.others);
}
voidmain()/*二叉排序树的查找*/
{
charq;
BiTreedt,p;
inti,num;
KeyTypej;
ElemTypek;
ElemTyper[10]={{2,22},{3,33},{4,44},{5,55},{6,66},{7,77},{8,88},{9,99},{1,11},{10,110}};/*测试数据*/
InitDSTable(&dt);/*构造空表*/
for(i=0;i<10;i++)
InsertBST(&dt,r[i]);/*依次插入数据元素*/
H1:
printf("<<<<<请选择功能数字项>>>>>");
printf("\n");
printf("1、遍历原表\n");
printf("2、查找元素\n");
printf("3、删除元素\n");
printf("4、插入元素\n");
printf("5、销毁表\n");
printf("6、退出");
printf("\n");
printf("请选择你需要的操作步:
");
scanf("%d",&num);
switch(num)
{
/*遍历所有元素*/
H2:
case1:
printf("原有的表遍历如下:
\n");
TraverseDSTable(dt,print);
printf("\n");
printf("按任意键返回.....");
getchar();
getchar();
gotoH1;/*返回功能模版*/
/*查找元素*/
H3:
case2:
printf("原有的表遍历如下:
\n");
TraverseDSTable(dt,print);
printf("\n");
printf("\n请输入你要查找的值:
");
scanf("%d",&j);
p=SearchBST(dt,j);
if(p)
{
printf("\n查找成功:
");
printf("(%d,%d)",p->data.key,p->data.others);
//getchar();
getchar();
printf("\n是否继续查找?
(Y/N):
");
q=getchar();
getchar();
if(q=='Y'||q=='y')
gotoH3;
else
{
gotoH1;
}
}
else
{
printf("查找失败,表中无此值,是否继续查找?
(Y/N):
");
getchar();
q=getchar();
if(q=='Y'||q=='y')
gotoH2;
else
{
gotoH1;
}
}
/*删除元素*/
H4:
case3:
printf("原有的表遍历如下:
\n");
TraverseDSTable(dt,print);
printf("\n");
printf("\n请输入你要删除的值:
");
scanf("%d",&j);
//getchar();
//q=getchar();
p=SearchBST(dt,j);
if(p)
{
printf("删除此值后:
\n");
DeleteBST(&dt,j);
TraverseDSTable(dt,print);
printf("\n是否继续删除?
(Y/N):
");
getchar();
q=getchar();
if(q=='Y'||q=='y')
gotoH4;
else
{
gotoH1;
}
}
else
{
printf("删除失败,表中无此值,请按任意键返回继续....");
printf("\n");
getchar();
getchar();
gotoH4;
}
/*插入元素*/
H5:
case4:
printf("原有的表遍历如下:
\n");
TraverseDSTable(dt,print);
printf("\n");
printf("请输入你要插入的值:
");
scanf("%d",&k.key);
p=SearchBST(dt,k.key);
if(!
p)
{
printf("插入此值后:
\n");
k.others=k.others+(N+1);
InsertBST(&dt,k);
TraverseDSTable(dt,print);
printf("\n");
printf("是否继续插入新值?
(Y|N):
");
getchar();
q=getchar();
if(q=='Y'||q=='y')
gotoH5;
else
{
gotoH1;
}
}
else
{
printf("插入失败,表中已存在此值,请返回");
getchar();
getchar();
gotoH5;
}
/*销毁表*/
case5:
DestroyDSTable(&dt);
printf("销毁成功....");
gotoH2;
/*退出系统*/
case6:
printf("\n\n\n任务完成,再见");
printf("\n\n\n");
system("pause");
}
}
5.代码分析和测试结果
1.主程序模块与各子程序模块间的调用关系:
intmain()
H()
switch()
InitDSTable(DT)InsertDSTable(DT,e)TraverseDSTable(dt,print)
构造空表插入元素遍历原表
SearchBST(T,key)DeleteBST(&dt,j)DestroyDSTable(&dt)
查找元素删除元素销毁表
其中H函数便于观察和返回相应操作,case实现小模块功能。
参考书籍:
数据结构C语言版、动态查找表实验分析等
2.测试结果
6.实验过程中的编程环境问题
VC++6.0的路径问题:
由于路径设置不匹配造成无法通过编译组建
如图:
解决方案:
通过在命令提示符下输入:
msdev/useenv运行。
强制使系统环境变量全高设置成正确值.一次性修复错误,从图标快捷进入也恢复正常。
7.思考与小结
在编程的时候遇到许多小错误,设计算法思路刚开始不够清晰,通过参考数据结构相关书籍上机调试和整合代码,逐渐认识并减少错误,最终完成了抽象数据类型动态查找表的各项操作,并巩固了动态查找表的所关联的数据结构知识。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实验 报告 动态 查找