云南大学数据结构实验7.docx
- 文档编号:29875461
- 上传时间:2023-08-03
- 格式:DOCX
- 页数:38
- 大小:55.22KB
云南大学数据结构实验7.docx
《云南大学数据结构实验7.docx》由会员分享,可在线阅读,更多相关《云南大学数据结构实验7.docx(38页珍藏版)》请在冰豆网上搜索。
云南大学数据结构实验7
实验难度:
A□B□C
序号
学号
姓名
成绩
指导教师
(签名)
学 期:
2017秋季学期
任课教师:
储星
实验题目:
查找算法的设计与实现
组员及组长:
承担工作:
联系电话:
电子邮件:
完成提交时间:
2018年12月29日
一、【实验构思(Conceive)】(10%)
(本部分应包括:
描述实验实现的基本思路,包括所用到的离散数学、工程数学、程序设计等相关知识,对问题进行概要性地分析)
二叉排序树的查找算法及算法原理:
对给定的二叉排序树,如果想知道某元素是否在其中出现,可以和根结点比较,如果相等结束;如果不等,若比其大,进入右子树;否则进入左子树;继续按照上面的方法,直到出现相等或者到某分支结束为止,返回查找信息。
哈希表的查找算法及其原理:
给定K值,根据造表时设定的哈希函数求得哈希地址,若表中此位置上没有记录,则查找不成功;否则比较关键字,若和给定值相等,则查找成功;否则根据造表时设定的处理冲突的方法找到“下一地址”,直至哈希表中某个位置为“空”或者表中所记录的关键字等于给定值时为止。
数据结构算法的知识:
表的定义、表项的表示、表的存储结构、哈希表的定义、哈希函数的构造方法、哈希表查找处理冲突的办法。
面向对象的程序设计相关知识:
C基本语法知识、类的定义、对象的生成调用、变量的传递。
二、【实验设计(Design)】(20%)
(本部分应包括:
抽象数据类型的定义和基本操作说明,程序包含的模块以及各模块间的调用关系,关键算法伪码描述及程序流程图等,如有界面则需包括界面设计,功能说明等)
抽象数据类型:
typedefintKeyType;
typedefstruct{
constchar*name;
intnamenum;
}Name;
typedefstruct{
Namedata;
intpos;
}HashTable;
typedefstructHash{
Namedata;
intpos;
structHash*next;
}*Hash_P,Hash_L;
typedefstructBSTNode{
KeyTypekey;
structBSTNode*lc,*rc;
}*BSTree;
抽象数据操作:
voidInsertBST(BSTree*bst,KeyTypekey)//若在二叉排序树中不存在关键字等于key的元素,插入该元素
voidCreateBST(BSTree*bst)//从键盘输入元素的值,创建相应的二叉排序树
BSTreesearch(KeyTypek,BSTreeroot)
BSTNode*DelBST(BSTreet,KeyTypek)//在二叉排序树t中删去关键字为k的结点
子函数:
intmenu_X()
intmenu_T()
intmenu_L()
voidinitName()
voidinitHashTable_X()
voidinitHashTable_T()
voidinitHashTable_L()
voidshow()
voidshow_L()
voidfindName_X()
voidfindName_T()
voidfindName_L()
intMenu()
三、【实现(Implement)】(30%)
(本部分应包括:
抽象数据类型各操作的具体实现代码、关键操作的具体算法实现、函数实现,主程序实现等,并给出关键算法的时间复杂度分析。
如有界面则需包括界面的关键实现方法等。
)
基本操作实现:
主函数:
voidmain()
{
intchoose,choose1,n;
KeyTypek;//查找关键字
BSTreeT;//BSTree*M;
boolf1=false,f2=false;//f1判断有序表是否创建,f2判断二叉排序树是否创建
while
(1)
{
choose=Menu();
choose1=0;
switch(choose)
{
case1:
system("cls");
{
while(choose1!
=4)
{
system("cls");
choose1=menu_X();
switch(choose1)
{
case1:
initName();
initHashTable_X();
_getch();
break;
case2:
findName_X();_getch();break;
case3:
show();_getch();break;
case4:
break;
}
}
}
break;
case2:
system("cls");
{
while(choose1!
=4)
{
system("cls");
choose1=menu_T();
switch(choose1)
{
case1:
initName();
initHashTable_T();
_getch();
break;
case2:
findName_T();_getch();break;
case3:
show();_getch();break;
case4:
break;
}
}
}
break;
case3:
system("cls");
{
while(choose1!
=4)
{
system("cls");
choose1=menu_L();
switch(choose1)
{
case1:
initName();
initHashTable_L();
_getch();
break;
case2:
findName_L();_getch();break;
case3:
show_L();_getch();break;
case4:
break;
}
}
}
break;
case4:
system("cls");
{
printf("建立二叉排序树,输入大于等于则退出输入:
\n");
CreateBST(&T);
f2=true;
break;
}
case5:
system("cls");
{
if(f2==true)
{
printf("请输入查找的关键字:
\n");
scanf("%d",&k);
if(search(k,T)!
=NULL)
printf("查找成功。
\n");
else
printf("查找失败。
\n");
}
else
printf("二叉排序树不存在\n");
break;
}
case6:
system("cls");
{
if(f2==true)
{
printf("请输入删除的关键字:
\n");
scanf("%d",&k);
T=DelBST(T,k);
}
else
printf("二叉排序树不存在\n");
break;
}
case7:
system("cls");
{
if(f2==true)
{
printf("请输入插入的关键字:
\n");
scanf("%d",&k);
InsertBST(&T,k);
}
else
printf("二叉排序树不存在\n");
break;
}
case0:
exit(0);
}
}
}
初始化哈希表:
HashTableHashList[HashNum];
voidinitHashTable_X(){
intpos;
intd,count;
for(intn=0;n HashList[n].data.name=""; HashList[n].data.namenum=0; HashList[n].pos=0; } for(inti=0;i count=1; pos=nameList[i].namenum%HashNum;//哈希函数 if(HashList[pos].pos==0){ HashList[pos].data=nameList[i]; HashList[pos].pos=1; //printf("不冲突! "); } else{ d=pos; while(HashList[d].pos! =0){ //printf("冲突了! "); d=(d+1)%HashNum; count++; } HashList[d].data=nameList[i]; HashList[d].pos=count; //printf("\n冲突了%d次的人是%s\n",count,nameList[i].name); } } printf("\n初始化完毕! "); } intdup[dupSize]; voidinitHashTable_T(){ intpos; intd,count; intk=0; for(intn=0;n HashList[n].data.name=""; HashList[n].data.namenum=0; HashList[n].pos=0; } for(intm=1;m { dup[k++]=m*m; dup[k++]=-m*m; } for(inti=0;i count=1; pos=nameList[i].namenum%HashNum;//哈希函数 if(HashList[pos].pos==0){ HashList[pos].data=nameList[i]; HashList[pos].pos=1; //printf("不冲突! "); } else{ d=pos;k=0; while(HashList[d].pos! =0){ //printf("冲突了! "); d=(d+HashNum+dup[k++])%HashNum; count++; } HashList[d].data=nameList[i]; HashList[d].pos=count; //printf("\n冲突了%d次的人是%s\n",count,nameList[i].name); } } printf("\n初始化完毕! "); } Hash_LHashList_L[HashNum_L]; voidinitHashTable_L(){ intpos,count=2; Hash_Pp,q; for(intm=0;m HashList_L[m].next=NULL; HashList_L[m].data.name=""; HashList_L[m].data.namenum=0; HashList_L[m].pos=0; } for(inti=0;i pos=nameList[i].namenum%HashNum_L; count=2; if(HashList_L[pos].pos==0){ //printf("\nthefirstif"); HashList_L[pos].data=nameList[i]; HashList_L[pos].pos=1; HashList_L[pos].next=NULL; //printf("——————不冲突! "); } else{ p=&HashList_L[pos]; while(p->next! =NULL){ p=p->next; count++; printf("冲突了! "); } q=(Hash_P)malloc(sizeof(Hash_L)); q->next=p->next; p->next=q; q->data=nameList[i]; q->pos=count; //printf("\n冲突了%d次的人是%s\n",count,nameList[i].name); } } printf("初始化完毕! "); } 哈希表查找: voidfindName_X(){ charfname[20]={0}; intfindNum=0,fhashNum=0,d; printf("请输入学要查找的姓名(一小写拼音的形式): "); scanf("%s",fname); for(intm=0;m<20;m++) findNum+=fname[m]; printf("\nfindNumis: %d\n",findNum); fhashNum=findNum%HashNum; if(HashList[fhashNum].data.namenum==0)printf("该姓名不存在! "); elseif(HashList[fhashNum].data.namenum==findNum)printf("该学生姓名为: %s\n该学生关键字为: %d\n该学生位置为: %d\n查找该学生冲突次数: %d\n", HashList[fhashNum].data.name,HashList[fhashNum].data.namenum,fhashNum,HashList[fhashNum].pos); else{ d=fhashNum; while(HashList[d].data.namenum! =findNum){ d=(d+1)%HashNum; } printf("该学生姓名为: %s\n该学生关键字为: %d\n该学生位置为: %d\n查找该学生冲突次数: %d\n", HashList[d].data.name,HashList[d].data.namenum,d,HashList[d].pos); } } voidfindName_T(){ charfname[20]={0}; intfindNum=0,fhashNum=0,d,k=0; printf("请输入学要查找的姓名(一小写拼音的形式): "); scanf("%s",fname); for(intm=0;m<20;m++) findNum+=fname[m]; printf("\nfindNumis: %d\n",findNum); fhashNum=findNum%HashNum; if(HashList[fhashNum].data.namenum==0)printf("该姓名不存在! "); elseif(HashList[fhashNum].data.namenum==findNum)printf("该学生姓名为: %s\n该学生关键字为: %d\n该学生位置为: %d\n查找该学生冲突次数: %d\n", HashList[fhashNum].data.name,HashList[fhashNum].data.namenum,fhashNum,HashList[fhashNum].pos); else{ d=fhashNum; while(HashList[d].data.namenum! =findNum){ d=(d+dup[k++]+HashNum)%HashNum; } printf("该学生姓名为: %s\n该学生关键字为: %d\n该学生位置为: %d\n查找该学生冲突次数: %d\n", HashList[d].data.name,HashList[d].data.namenum,d,HashList[d].pos); } } voidfindName_L(){ charfname[20]={0}; intfindNum=0,fhashNum=0,pos; Hash_Pp; printf("请输入学要查找的姓名(一小写拼音的形式): "); scanf("%s",fname); for(intm=0;m<20;m++) findNum+=fname[m]; printf("\nfindNumis: %d\n",findNum); pos=findNum%HashNum_L; p=&HashList_L[pos]; if(! p)printf("改姓名不存在! "); while(p&&p->data.namenum! =findNum)p=p->next; if(p->data.namenum==findNum){ printf("该学生姓名为: %s\n该学生关键字为: %d\n该学生位置为: %d\n查找该学生冲突次数: %d\n", p->data.name,p->data.namenum,pos,p->pos); } } 四、【测试结果(Testing)】(10%) (本部分应包括: 对实验的测试结果,应具体列出每次测试所输入的数据以及输出的数据,并对测试结果进行分析,可附截图) 截图如下: 五、【实验总结】(10%) (本部分应包括: 自己在实验中完成的任务,及存在的问题,所完成实验过程中的具体经验总结、心得) 这次实验使我对Hash查找表、Hash搜索算法有了熟练的掌握。 在设计程序时,摆在我面前有以下几个难题: 首先,如何用C#生成符合一定规则的HashTable? 这个问题花了我不少时间,最后通过定义一个结构体数组来避免指针的缺失,解决了此问题。 其次,在生成HashTable之后,如何实现HashTable搜索算法呢? 我觉得还是继续使用哈希法推算index,如果不符合要求则继续使用再哈希法,直至达到符合要求的表项或者条件出错退出。 利用哈希法选择index能够很有效的减少堆积,降低平均查找长度,实现快速存取的目的。 本次试验,有些同学帮助我很多,一起讨论并解决了不少问题,使得程序更佳完善。 一个人不可能面面俱到,这时同学的帮助与合作尤为重要,一定要虚心求教,认真倾听别人的意见,不要认为自己做的东西才是最好的,只有这样才能进步。 六、思考题(10%) (注: 选择C难度的才需要填写“项目运作描述”,其他难度的只需完成思考题) (项目运作描述应包括: 项目的成本效益分析,应用效果等) 我所设计的这个程序可以实现对动态查找表中的二叉排序树的建立与查找,包括新结点的插入和删除等操作。 通过哈希表的构造、查找和维护,能够对学生进行按姓名的哈希查找。 七、【代码】(10%) (本部分应包括: 完整的代码及充分的注释。 注意纸质的实验报告无需包括此部分。 格式统一为,字体: Georgia,行距: 固定行距12,字号: 小五) #include #include #include #include #include #defineNameNum30 #defineHashNum50 #defineHashNum_L17 #definedupSize15 typedefintKeyType; typedefstruct{ constchar*name; intnamenum; }Name; typedefstruct{ Namedata; intpos; }HashTable; typedefstructHash{ Namedata; intpos; structHash*next; }*Hash_P,Hash_L; typedefstructBSTNode{ KeyTypekey; structBSTNode*lc,*rc; }*BSTree; voidInsertBST(BSTree*bst,KeyTypekey)//若在二叉排序树中不存在关键字等于key的元素,插入该元素 { BSTrees; if(*bst==NULL)//递归结束条件 { s=(BSTree)malloc(sizeof(BSTNode)); s->key=key; s->lc=NULL; s->rc=NULL; *bst=s; } elseif(key<(*bst)->key) InsertBST(&((*bst)->lc),key);//将s插入左子树 elseif(key>(*bst)->key) InsertBST(&((*bst)->rc),key);//将s插
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 云南大学 数据结构 实验
![提示](https://static.bdocx.com/images/bang_tan.gif)