数据结构实验报告动态查找表实验报告Word格式文档下载.docx
《数据结构实验报告动态查找表实验报告Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告动态查找表实验报告Word格式文档下载.docx(19页珍藏版)》请在冰豆网上搜索。
动态查找表DT存在,key为和关键字类型相同的给定值。
若DT中存在其关键字等于key的数据元素,则函数值为该元素的值或在表中的位置,否则为“空”。
InsertDSTable(&
DT,e);
动态查找表DT存在,e为待插入的数据元素。
若DT中不存在其关键字等于e.key的数据元素,则插入e到DT。
DeleteDSTable(&
DT,key);
若DT中存在其关键字等于key的数据元素,则删除之。
TraverseDSTable(DT,visit());
动态查找表DT存在,visit是对结点操作的应用函数。
按某种次序对DT的每个结点调用函数visit()一次且至多一次,一旦visit()失败,则操作失败。
}ADTDynamicSearchTable
二.存储结构定义:
公用头文件DS0.h和宏定义:
#include<
stdio.h>
/*EOF(=^Z或F6),NULL*/
stdlib.h>
#defineTRUE1
#defineFALSE0
#defineOK1
#defineN10/*数据元素个数*/
typedefintStatus;
/*Status是函数的类型,其值是函数结果状态代码,如OK等*/
typedefintKeyType;
/*设关键字域为整型*/
#defineEQ(a,b)((a)==(b))
#defineLT(a,b)((a)<
(b))
二叉排序树存储结构:
二叉排序树的类型BiTree定义如下:
typedefstruct
{
KeyTypekey;
intothers;
}ElemType;
/*数据元素类型*/
typedefElemTypeTElemType;
typedefstructBiTNode
TElemTypedata;
structBiTNode*lchild,*rchild;
/*左右孩子指针*/
}BiTNode,*BiTree;
三、算法设计:
/*操作结果:
构造一个空的动态查找表DT*/
StatusInitDSTable(BiTree*DT)
*DT=NULL;
returnOK;
}
/*初始条件:
动态查找表DT存在。
操作结果:
销毁动态查找表DT*/
voidDestroyDSTable(BiTree*DT)/*同bo6-2.c*/
if(*DT)/*非空树*/
{
if((*DT)->
lchild)/*有左孩子*/
(*DT)->
lchild);
/*销毁左孩子子树*/
rchild)/*有右孩子*/
rchild);
/*销毁右孩子子树*/
free(*DT);
/*释放根结点*/
/*空指针赋0*/
}
/*在根指针T所指二叉排序树中递归地查找某关键字等于key的数据元素,*/
/*若查找成功,则返回指向该数据元素结点的指针,否则返回空指针。
*/
BiTreeSearchBST(BiTreeT,KeyType1key)
if((!
T)||EQ(key,T->
data.key))
returnT;
/*查找结束*/
elseifLT(key,T->
data.key)/*在左子树中继续查找*/
returnSearchBST(T->
lchild,key);
else
rchild,key);
/*在右子树中继续查找*/
/*在根指针T所指二叉排序树中递归地查找其关键字等于key的数据元素,若查找*/
/*成功,则指针p指向该数据元素结点,并返回TRUE,否则指针p指向查找路径上*/
/*访问的最后一个结点并返回FALSE,指针f指向T的双亲,其初始调用值为NULL*/
voidSearchBST1(BiTree*T,KeyType1key,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);
/*在左子树中继续查找*/
rchild,key,*T,p,flag);
/*当二叉排序树T中不存在关键字等于e.key的数据元素时,插入e并返回TRUE,*/
/*否则返回FALSE。
StatusInsertBST(BiTree*T,ElemType1e)
BiTreep,s;
Statusflag;
SearchBST1(T,e.key,NULL,&
p,&
flag);
flag)/*查找不成功*/
s=(BiTree)malloc(sizeof(BiTNode));
s->
data=e;
lchild=s->
rchild=NULL;
p)
*T=s;
/*被插结点*s为新的根结点*/
elseifLT(e.key,p->
p->
lchild=s;
/*被插结点*s为左孩子*/
rchild=s;
/*被插结点*s为右孩子*/
returnTRUE;
returnFALSE;
/*树中已有关键字相同的结点,不再插入*/
/*从二叉排序树中删除结点p,并重接它的左或右子树。
voidDelete(BiTree*p)
BiTreeq,s;
(*p)->
rchild)/*右子树空则只需重接它的左子树(待删结点是叶子也走此分支)*/
q=*p;
*p=(*p)->
lchild;
free(q);
elseif(!
lchild)/*只需重接它的右子树*/
rchild;
else/*左右子树均不空*/
s=(*p)->
while(s->
rchild)/*转左,然后向右到尽头(找待删结点的前驱)*/
q=s;
s=s->
(*p)->
data=s->
data;
/*s指向被删结点的"前驱"(将被删结点前驱的值取代被删结点的值)*/
if(q!
=*p)
q->
rchild=s->
/*重接*q的右子树*/
/*重接*q的左子树*/
free(s);
/*若二叉排序树T中存在关键字等于key的数据元素时,则删除该数据元素结点,*/
/*并返回TRUE;
否则返回FALSE。
StatusDeleteBST(BiTree*T,KeyType1key)
*T)/*不存在关键字等于key的数据元素*/
ifEQ(key,(*T)->
data.key)/*找到关键字等于key的数据元素*/
Delete(T);
DeleteBST(&
动态查找表DT存在,Visit是对结点操作的应用函数*/
按关键字的顺序对DT的每个结点调用函数Visit()一次且至多一次*/
voidTraverseDSTable(BiTreeDT,void(*Visit)(ElemType1))
if(DT)
TraverseDSTable(DT->
lchild,Visit);
/*先中序遍历左子树*/
Visit(DT->
data);
/*再访问根结点*/
rchild,Visit);
/*最后中序遍历右子树*/
四、编译:
1.初次编译会出现很多错误,这主要是写程序时的粗心大意还有一些潜在的定于或逻辑错误,第一次运行如下:
2.错误很多,经过一番调试才发现定义结构体时出了问题,有些没用到,有些重定义了,调试后如下:
3.此时只剩下很少错误,很明显是i未定义,经过修改调试后编译通过。
五、测试
voidprint(ElemTypec)/*以下主函数调用*/
printf("
(%d,%d)"
c.key,c.others);
Voidmain()/*用于测试二叉排序树的查找*/
charq;
BiTreedt,p;
inti,select;
KeyTypej;
ElemTypek;
ElemTyper[10]={{45,1},{12,2},{53,3},{3,4},{37,5},{24,6},{100,7},{61,8},{90,9},{70,10}};
/*测试数据*/
dt);
/*构造空表*/
for(i=0;
i<
10;
i++)
InsertBST(&
dt,r[i]);
/*依次插入数据元素*/
H1:
=============动态查找表演示系统==========="
);
\n"
1、遍历原有表\n"
2、查找表内值\n"
3、删除表内值\n"
4、插入一个值\n"
5、销毁表\n"
6、退出系统"
请选择你需要的操作(1~6):
"
scanf("
%d"
&
select);
switch(select)
H2:
case1:
printf("
原有的表遍历如下:
TraverseDSTable(dt,print);
按任意键返回....."
getchar();
system("
cls"
gotoH1;
H3:
case2:
\n请输入你要查找的值:
j);
p=SearchBST(dt,j);
if(p)
\n查找成功:
(%d,%d)"
p->
data.key,p->
data.others);
//getchar();
\n是否继续查找?
(Y/N):
q=getchar();
if(q=='
Y'
||q=='
y'
)
gotoH3;
}
查找失败,表中无此值,是否继续查找?
gotoH2;
H4:
case3:
\n请输入你要删除的值:
//q=getchar();
删除此值后:
dt,j);
\n是否继续删除?
gotoH4;
删除失败,表中无此值,请按任意键返回继续...."
H5:
case4:
请输入你要插入的值:
k.key);
p=SearchBST(dt,k.key);
插入此值后:
k.others=k.others+(N+1);
dt,k);
是否继续插入新值?
(Y|N):
gotoH5;
插入失败,表中已存在此值,请按任意键返回继续...."
case5:
DestroyDSTable(&
销毁成功...."
case6:
system("
\n\n\n\n\n\n\n\n\n============谢谢使用!
============"
\n\n\n"
pause"
说明:
(1)、此二叉排序树以下面为原始测试数据:
{45,1},{12,2},{53,3},{3,4},{37,5},{24,6},{100,7},{61,8},{90,9},{78,10}
主界面如下:
(2)、若选择‘1’,则显示遍历出来的二叉排序树动态查找表,如下图:
(3)、若选择‘2’则提示用户输入要查找的值,若存在,则显示查找成功,若没有此值,则提示是否继续查找,如下图:
(4)、若输入3,则提示用户输入想要删除的值,若存在此值,则显示删除后的表,若不存在此值,则显示删除失败,如下图:
(5)、若选择‘4’,则提示用户输入一个想要插入的值,若表中无此元素,则显示插入后的表,若已存在,则提示插入失败,如下图:
(6)、若选择‘5’,则销毁此表,并显示销毁之后的表,如下图:
(7)、若选择‘6’,则退出系统,显示结束系统界面:
六、二叉排序树查找分析:
在二叉排序树上查找其关键字等于给定值的结点的过程,恰是走了一条从根结点到该结点的路径的过程,和给定值比较的关键字个数等于路径长度加1(或结点所在层次数),因此,和折半查找类似,与给定值比较的关键字个数不超过树的深度。
然而,折半查找长度为n的表的判定树是唯一的,而含有n个结点的二叉平衡树却是不唯一。
在随机的情况下,二叉排序树的平均查找长度和logn是等数量级的,然而,在某些情况下(有人研究证明,这种情况出现的概率约为46.5%),尚需在构成二叉排序树的过程中进行‘平衡化处理’,成为二叉平衡树。
七、思考与小结
思考:
动态查找表跟静态查找表不一样的地方在于他有插入删除功能,这两大功能也是继查找功能后最大的功能,所以核心代码还是这两三个函数,为了更好的测试这些功能,稍微写了一下很粗糙的界面和出错处理,也算是一种方便吧。
小结:
这些代码其实都不是原创,都是根据参考书的代码看懂后稍加修改而成的,这也是出现很多错误的原因,不过最终还是把错误都改完了,也实现了相应的操作,也算是对这动态查找表有了更深入的了解。