目录
【实验目的】
【实验预习】
【实验内容】
1. 编写程序,实现顺序查找和折半查找
2. 编写程序,实现哈希表的构造和查找及哈希冲突的检测方法
【实验目的】
1. 掌握查找表、动态查找表、静态查找表和平均查找长度的概念
2. 掌握线性表中顺序表查找和折半查找的方法
3. 学会哈希函数的构造方法,处理冲突的机制及哈希表的查找
4. 掌握二叉排序树的构造方法和查找过程
【实验预习】
1. 顺序查找。顺序查找的平均查找长度和查找不成功时的比较次数
2. 折半查找。折半查找的平均查找长度
3. 二叉排序树和平衡二叉树
4. 哈希表和哈希查找
5. 处理冲突的方法
【实验内容】
1. 编写程序,实现顺序查找和折半查找
(1)回答下面问题并与运行结果进行比较:
测试数据:{49,38,65,97,76,13,27,52,89}
① 顺序查找
查找key=76,查找成功比较次数
查找key=25,查找不成功比较次数
② 折半查找
查找key=76,查找成功比较次数
查找key=25,查找不成功比较次数
(2)参考程序如下,请补充完整
#include<stdio.h>
#define MAX 100
#define KeyType int
typedef struct{
KeyType key;
}table;
int inputSeqData(table R[]);
int SeqSearch(table R[],int n,KeyType k);
int inputBinData(table R[]);
int BinSearch(table R[],int n,KeyType k);
int main(){
table R[MAX];
int select,n,i;
KeyType k;
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("\ninput choice:");
scanf("%d",&select);
getchar();
switch(select){
case 1:
printf("\n1-输入顺序查找表\n");
n=inputSeqData(R);
printf("\n顺序查找表元素:");
for(i=1;i<n;i++){
printf("%d ",R[i].key);
}
printf("\n");
getchar();
break;
case 2:
printf("\n2-顺序查找\n");
printf("\n输入查找关键字:");
scanf("%d",&k);
i=SeqSearch(R,n,k);
if(i==0){
printf("\n未找到key=%d\n",k);
}else{
printf("\n查找成功!k=%d位置序号:%d\n",k,i);
}
getchar();
break;
case 3:
printf("\n3-输入折半查找表\n");
n=inputBinData(R);
printf("\n折半查找表元素:");
for(i=0;i<n;i++){
printf("%d ",R[i].key);
}
printf("\n");
getchar();
break;
case 4:
printf("\n4-折半查找\n");
printf("\n输入查找关键字:");
scanf("%d",&k);
i=BinSearch(R,n,k);
if(i==0){
printf("\n未找到key=%d\n",k);
}else{
printf("\n查找成功!k=%d位置序号:%d\n",k,i+1);
}
getchar();
break;
case 0:
break;
default:
break;
}
}while(select);
return 0;
}
int inputSeqData(table R[]){
int i;
KeyType a;
printf("\n输入顺序查找表元素(以非数值为输入结束):");
i=1;
while(scanf("%d",&a)==1){
R[i].key=a;
i++;
}
return i;
}
int SeqSearch(table R[],int n,KeyType k)
{
int i=n;
R[0].key=k;
while(R[i].key!=k){
i--;
}
return i;
}
int inputBinData(table R[]){
int i,j,t;
KeyType a;
printf("\n输入折半查找表元素(以非数值为输入结束):");
t=0;
while(scanf("%d",&a)==1){
for(i=0;i<t;i++){
if(a<R[i].key){
break;
}
}
for(j=t;j>=i;j--){
R[j+1].key=R[j].key;
}
R[i].key=a;
t++;
}
return t;
}
int BinSearch(table R[],int n,KeyType k){
int low,mid,high;
low=1;
high=n;
while(low<high){
mid=(low+high)/2;
if(k==R[mid].key){
return mid;
}
if(k<R[mid].key){
high=mid-1;
}else{
low=mid+1;
}
}
return 0;
}
2. 编写程序,实现哈希表的构造和查找及哈希冲突的检测方法
(1)回答下面问题,并域运行结果比较:
设关键字序列为{16 74 60 43 54 90 46 31 29 88 77 e}
①采用线性探测法,写出构造的哈希表
②采用二次探测法,写出构造的哈希表
③线性探测法哈希查找key值为74,查找成功探查 次
线性探测法哈希查找key值为100,查找不成功探查 次
④二次探测法哈希查找key值为29,查找成功探查 次
二次探测法哈希查找key值为2,查找不成功探查 次
(2)参考程序如下,请补充完整
#include<stdio.h>
#include<malloc.h>
#define MAXSIZE 15
#define MAX 15
#define NULLKEY 0
#define KeyType int
#define P 13
#define OK 1
#define ERROR 0
typedef struct{
KeyType key;
}HashNode;
typedef struct{
HashNode data[MAXSIZE];
int count;
int sizeindex;
}HashTable;
int d1[MAX]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14};
int d2[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};
int InsertHash(HashTable *H,int e,int d[]);
int CreateHash(HashTable *H,int d[]);
int SearchHash(HashTable *H,int e,int d[]);
void InitHash(HashTable *H);
void InitHash(HashTable *H){
int i;
for(i=0;i<MAXSIZE;i++){
H->data[i].key=NULLKEY;
}
H->count=0;
H->sizeindex=MAXSIZE;
}
int InsertHash(HashTable *H,int e,int d[]){
int k,i=1;
k=e%P;
while(H->data[k].key!=NULLKEY){
k=(e%P+d[i]+MAXSIZE)%MAXSIZE;
i++;
if(i>MAX) return ERROR;
}
H->data[k].key=e;
H->count++;
return OK;
}
int SearchHash(HashTable *H,int e,int d[]){
int k,i=1;
k=e%P;
while(H->data[k].key!=NULLKEY&&H->data[k].key!=e){
k=(e%P+d[i]+MAXSIZE)%MAXSIZE;
i++;
if(i>MAX) break;
}
if(H->data[k].key==e) return k;
else return -1;
}
int CreateHash(HashTable *H,int d[]){
KeyType a;
printf("\n输入数据元素(以非数值为输入结束):");
while(scanf("%d",&a)==1){
if(SearchHash(H,a,d)!=-1)
continue;
InsertHash(H,a,d);
if(H->count>=MAXSIZE)
return ERROR;
}
return OK;
}
int main(){
HashTable h;
KeyType e;
int i,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("\ninput choice:");
scanf("%d",&select);
getchar();
switch(select){
case 1:
case 2:
if(select==1){
printf("\n1-线性探测构造哈希表\n");
q=d1;
}else{
printf("\n2-二次探测构造哈希表\n");
q=d2;
}
InitHash(&h);
if(!(i=CreateHash(&h,q)))
printf("\n哈希表构造失败!\n");
else{
printf("\n哈希表:\n");
for(i=0;i<h.sizeindex;i++){
printf("%d ",h.data[i].key);
}
}
printf("\n");
getchar();
break;
case 3:
case 4:
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,i);
else{
printf("\n%d在哈希表中下标为%d\n",e,i);
}
getchar();
break;
case 0:
break;
default:
break;
}
}while(select);
return 0;
}