实验八查找.docx
《实验八查找.docx》由会员分享,可在线阅读,更多相关《实验八查找.docx(11页珍藏版)》请在冰豆网上搜索。
![实验八查找.docx](https://file1.bdocx.com/fileroot1/2023-1/8/64c5e98d-e327-43a0-874f-30f6a75e2a35/64c5e98d-e327-43a0-874f-30f6a75e2a351.gif)
实验八查找
实验八查找
【实验目的】
1、掌握查找表、动态查找表、静态查找表和平均查找长度的概念。
2、掌握线性表中顺序查找和折半查找的方法。
3、学会哈希函数的构造方法,处理冲突的机制以及哈希表的查找。
4、掌握二叉排序树的构造方法和查找过程;
【实验学时】
2学时
【实验预习】
回答以下问题:
1、顺序查找。
顺序查找的平均查找长度和查找不成功时的比较次数。
2、折半查找。
折半查找的平均查找长度。
3、二叉排序树和平衡二叉树。
4、哈希表和哈希查找
5、处理冲突的方法有哪几种?
【实验内容和要求】
1、编写程序exp8_1.c,实现顺序查找和折半查找。
补充完整程序,调试运行测试数据:
(1)顺序查找表{8,15,19,26,33,41,47,52,64,90}
查找key=41查找成功比较次数:
________
查找key=100查找不成功比较次数:
______
(2)折半查找表{12,15,20,29,33,33,48,65,89}
查找key=29查找成功比较次数:
________
查找key=99查找不成功比较次数:
______
exp8_1.c参考程序如下:
#include
#defineMAX100
#defineKeyTypeint
/*静态查找表的顺序存储结构*/
typedefstruct
{
KeyTypekey;/*关键字值项*/
}table;
intinputSeqData(tableR[]);/*创建顺序查找表*/
intSeqSearch(tableR[],intn,KeyTypek);/*顺序查找算法*/
intinputBinData(tableR[]);/*创建折半查找表,按照增序*/
intBinSearch(tableR[],intn,KeyTypek);/*折半查找算法*/
intmain()
{
tableR[MAX];
intselect,n,i;
KeyTypek;
do
{
printf("\n***************MENU******************\n");
printf("1.输入顺序查找表\n");
printf("2.顺序查找\n");
printf("3.输入折半查找表\n");
printf("4.折半查找\n");
printf("0.EXIT");
printf("\n***************MENU******************\n");
printf("\ninputchoice:
");
scanf("%d",&select);
getchar();
switch(select)
{
case1:
printf("\n1-输入顺序查找表\n");
n=inputSeqData(R);
printf("\n顺序查找表元素:
");
for(i=0;iprintf("%d",R[i].key);
printf("\n");
getchar();
break;
case2:
printf("\n2-顺序查找\n");
printf("\n输入查找关键字:
");
scanf("%d",&k);
i=SeqSearch(R,n,k);
if(i==-1)
printf("\n未找到key=%d!
\n",k);
else
printf("\n查找成功!
k=%d位置序号:
%d\n",k,i);
getchar();
break;
case3:
printf("\n3-输入折半查找表\n");
n=inputBinData(R);
printf("\n折半查找表元素:
");
for(i=0;iprintf("%d",R[i].key);
printf("\n");
getchar();
break;
case4:
printf("\n4-折半查找\n");
printf("\n输入查找关键字:
");
scanf("%d",&k);
i=BinSearch(R,n,k);
if(i==-1)
printf("\n未找到key=%d!
\n",k);
else
printf("\n查找成功!
k=%d位置序号:
%d\n",k,i);
getchar();
break;
case0:
break;
default:
break;
}
}
while(select);
return0;
}
/*创建顺序查找表*/
intinputSeqData(tableR[])
{
inti;
KeyTypea;
printf("\n输入顺序查找表元素(以非数值为输入结束):
");
i=0;
while(scanf("%d",&a)==1)
{
R[i].key=a;
i++;
}
returni;/*返回顺序查找表长度*/
}/*inputSeqData*/
/*
(1)---顺序查找算法,返回查找到位置序号,,否则返回-1*/
intSeqSearch(tableR[],intn,KeyTypek)
{
}/*SeqSearch*/
/*创建折半查找表,按照增序*/
intinputBinData(tableR[])
{
inti,j,t;
KeyTypea;
printf("\n输入折半查找表元素(以非数值为输入结束):
");
t=0;
while(scanf("%d",&a)==1)
{
for(i=0;iif(abreak;
for(j=t;j>=i;j--)
R[j+1].key=R[j].key;/*移动位置*/
R[i].key=a;
t++;
}
returnt;/*返回折半查找表长度*/
}/*inputBinData*/
/*
(2)---折半查找算法,返回查找到位置序号,否则返回-1*/
intBinSearch(tableR[],intn,KeyTypek)
{
}/*BinSearch*/
2、编写程序exp8_2.c,实现哈希表的创建和查找以及哈希冲突的检测方法。
补充完整程序,调试运行测试数据,设关键字序列为{1674604354904631298877e}:
(1)采用线性探测法,写出构造的哈希表:
(2)采用二次探测法,写出构造的哈希表:
(3)线性探测法哈希查找key值为74,查找成功探查_____次。
线性探测法哈希查找key值为100,查找不成功探查_____次。
(4)二次探测法哈希查找key值为29,查找成功探查_____次。
线性探测法哈希查找key值为2,查找不成功探查_____次。
exp8_2.c程序代码参考如下:
/*采用开放地址法构造哈希表*/
#include
#include
#defineMAXSIZE25/*哈希表分配存储空间大小*/
#defineMAX17/*冲突上限*/
#defineNULLKEY0/*NULLKEY为空结点标记*/
#defineKeyTypeint/*哈希表元素类型*/
#defineP13/*哈希函数采用除留取余,P因子大小*/
#defineOK1/*成功标识*/
#defineERROR0/*失败标识*/
#defineDUPLICATE-1/*关键字重复标识*/
/*哈希表结点存储结构*/
typedefstruct
{
KeyTypekey;
}HashNode;
/*哈希表存储结构*/
typedefstruct
{
HashNodedata[MAXSIZE];
intcount;/*当前表中元素个数*/
intsizeindex;/*当前哈希表容量*/
}HashTable;
intd1[MAX]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};/*线性探测序列*/
intd2[MAX]={0,1,-1,2*2,-2*2,3*3,-3*3,4*4,-4*4,5*5,-5*5,6*6,-6*6,7*7,-7*7};/*二次探测序列*/
intInsertHash(HashTable*H,inte,intd[]);/*计算哈希地址,插入哈希表*/
intCreateHash(HashTable*H,intd[]);/*构造哈希表*/
intSearchHash(HashTable*H,inte,intd[]);/*哈希查找*/
voidInitHash(HashTable*H);/*初始化哈希表*/
voidmenu();
/*初始化哈希表*/
voidInitHash(HashTable*H)
{
inti;
for(i=0;i{
H->data[i].key=NULLKEY;/*设置当前位置为空闲*/
}
H->count=0;
H->sizeindex=MAXSIZE;
}/*InitHash*/
/*
(1)---计算哈希地址,插入哈希表。
插入成功返回成功标识否则返回失败标识*/
intInsertHash(HashTable*H,inte,intd[])
{
}/*InsertHash*/
/*构造哈希表*/
intCreateHash(HashTable*H,intd[])
{
KeyTypea;
printf("\n输入数据元素(以非数值为输入结束):
");
while(scanf("%d",&a)==1)
{
if(SearchHash(H,a,d)!
=-1)/*若发现有重复关键字,返回*/
returnDUPLICATE;
InsertHash(H,a,d);/*插入元素到哈希表*/
if(H->count>=MAXSIZE)/*判断哈希表满*/
returnERROR;
}
returnOK;
}/*CreateHash*/
/*哈希查找*/
intSearchHash(HashTable*H,inte,intd[])
{
}/*SearchHash*/
intmain()
{
HashTableh;
KeyTypee;
inti,select,*q;
do
{
printf("\n***************MENU******************\n");
printf("1.线性探测构造哈希表\n");
printf("2.二次探测构造哈希表\n");
printf("3.线性探测哈希查找\n");
printf("4.二次探测哈希查找\n");
printf("0.EXIT");
printf("\n***************MENU******************\n");
printf("\ninputchoice:
");
scanf("%d",&select);
getchar();
switch(select)
{
case1:
case2:
if(select==1)
{
printf("\n1-线性探测构造哈希表\n");
q=d1;
}
else
{
printf("\n2-二次探测构造哈希表\n");
q=d2;
}
InitHash(&h);/*初始化哈希表*/
if(!
(i=CreateHash(&h,q)))
printf("\n哈希表构造失败!
\n");
elseif(i==DUPLICATE)
printf("\n哈希表具有重复关键字!
\n");
else
{
printf("\n哈希表:
\n");
for(i=0;iprintf("%d",h.data[i].key);
}
printf("\n");
getchar();
break;
case3:
case4:
if(select==3)
{
printf("\n3-线性探测哈希查找\n");
q=d1;
}
else
{
printf("\n4-二次探测哈希查找\n");
q=d2;
}
printf("\n输入查找关键字:
");
scanf("%d",&e);
if((i=SearchHash(&h,e,q))==-1)
printf("\n%d未找到\n",e);
else
printf("\n%d在哈希表中下标为%d\n",e,i);
getchar();
break;
case0:
break;
default:
break;
}
}
while(select);
return0;
}
【拓展实验】
3、已知一个个数为12的数据元素序列为{Dec,Feb,Oct,June,Sept,Aug,Apr,May,July,Jan,Mar},要求编写程序:
(1)按各个数据元素的顺序(字母大小顺序)构造一棵二叉排序树,并按顺序打印排序结果。
(2)查找数据Sdept是否存在。
【实验小结】