一、 实验目的
1. 掌握查找的不同方法,并能用高级语言实现查找算法;
2. 熟练掌握二分查找法的构造和查找方法。
3. 熟练掌握哈希表查找方法。
二、 实验内容
1. 编写一个程序,输出在顺序表中采用二分查找法查找给定关键字的过程。
2. 编写一个程序,输出在顺序表{8、14、6、9、10、22、34、18、19、31、40、38、54、66、46、71、78、68、80、85、100、94、88、96、87}中采用分块查找法(每块的块长为5,共有5块)查找关键字46的过程。
3. 设计一个程序,实现哈希表的相关运算,并完成如下功能:
(1) 建立序列{16,74,60,43,54,90,46,31,29,88,77}的哈希表A[0..12],哈希函数为:H(key)=key%11,并采用线性探测再散列法解决冲突。
(2) 在上述哈希表中查找关键字为29的元素。
三、 实验要求
1. 使用C语言完成算法设计和程序设计并上机调试通过。
2. 撰写实验报告,提供实验结果和数据。
3. 写出算法设计小结和心得。
四、 程序源代码
第一题:
#include<stdio.h>
#include<stdlib.h>
#define OK 1
typedef struct{
int *elem;
int length;
int listsize;
}SSTable;
SSTable L;
int InsertList_Sq(SSTable &L,int i,int e)
{
q=&(L.elem[i]);
for(p=&(L.elem[L.length-1]);p>=q;p–)
*(p+1)=*p;
*q=e;
L.length++;
return OK;
}
int Search_bin(SSTable L,int key){
int low=1,high=L.length,mid=(low+high)/2,i=1,find=0;
while(low<=high&&(!find)){
mid=(low+high)/2;
printf(“第%d次查找的信息 low=%d\tmid=%d\thigh=%d\t所指向的值=%d\n”,i,low,mid,high,L.elem[mid]);
i++;
if(key==L.elem[mid])
find=1;
else
if(key<L.elem[mid]) high=mid-1;
else
low = mid+1;
}
if(find)
return mid;
else
return -1;
}
void main(){
InitList_Sq(L);
int key,m,n,i;
int num;
printf(“1:输入元素.2:输入想要查找的关键字.3:输出查找过程.4:输出所查找到的关键字\n”);
while(1){
printf(“输入选择\n”);
scanf(“%d”,&i);
switch(i){
case 1:
printf(“请输入要插入的元素个数:”);
scanf(“%d”,&num);
printf(“输入元素”);
for(i=1;i<=num;i++){
scanf(“%d”,&n);
InsertList_Sq(L,i,n);
}
break;
case 2:
printf(“输入关键字\n”);
scanf(“%d”,&key);
break;
case 3:
m=Search_bin(L,key);
break;
case 4:
printf(“输出查找的关键字\n”);
printf(“%d\n”,L.elem[m]);
break;
default:
printf(“输入错误”);
break;
}
}
}
第二题
#include<stdio.h>
#include<stdlib.h>
#define OK 1
typedef struct{
int elem[100];
int length;
}SqList;
SqList L;
typedef struct{
int elem[100];
int link[100];
int length;
}SuoYinTable;
SuoYinTable SY;
int InsertList_Sq(SqList &L,int i,int n)
{
int *p,*q;
q=&(L.elem[i]);
for(p=&(L.elem[L.length-1]);p>=q;p–)
*(p+1)=*p;
*q=n;
L.length++;
return OK;
}
int max(SqList &L,int n,int i)
{
int maxi=1,a=L.length/n;
for(int j=1+a*i;j<=a+a*i;j++)
if(L.elem[maxi]<L.elem[j])
maxi=j;
return maxi;
}
int Search(SuoYinTable &SY,int key)
{
int low=0,high=SY.length-1,mid,i,count=1;
int b=L.length/SY.length;
while(low<=high){
mid=(low+high)/2;
printf(“第%d次查询:low=%d\tmid=%d\thigh=%d\t指向的值是 %d\n”,count,low,mid,high,SY.elem[mid]);
if(SY.elem[mid]==key)
return SY.link[mid];
if(SY.elem[mid]>=key)
high=mid-1;
else
low=mid+1;
count++;
}
if(low<SY.length)
{
printf(“在第%d块中查找元素%d\n”,mid+1,key);
int i=low*b;
printf(“输出顺序查找过程:\n”);
while (i<low*b+b&& L.elem[i]!=key)
{
i++;
printf(“%d “,L.elem[i]);
}
printf(“\n”);
if (i<=low*b+b)
return i;
else
return -1;
}
return -1;
}
void main()
{
int i,n,num,key;
printf(“1.创建顺序表,2.创建索引表,3.输入想要查找的关键字\n”);
while(1)
{
printf(“请输入选择:\n”);
scanf(“%d”,&n);
switch(n)
{
case 1:
printf(“输入元素个数:\n”);
scanf(“%d”,&num);
printf(“输入元素:\n”);
for(i=1;i<=num;i++){
scanf(“%d”,&n);
InsertList_Sq(L,i,n);
}
break;
case 2:
printf(“输入分的块数:\n”);
scanf(“%d”,&n);
for(i=0;i<n;i++){
SY.elem[i]=L.elem[max(L,n,i)];
}
SY.length=n;
break;
case 3:
printf(“输入关键字:\n”);
scanf(“%d”,&key);
i=Search(SY,key);
if(L.elem[i]==key)
printf(“元素%d的位置是%d\n”,key,i);
else
printf(“元素%d不在表中\n”,key);
break;
default:
printf(“输入错误”);
break;
}
}
}
第三题
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 100
#define FALSE 0
#define OK 1
typedef struct{
int elem[100];
int length;
}SqList;
SqList L;
typedef struct {
int key;
} HashTable[MaxSize];
int InsertList_Sq(SqList &L,int i,int e)
{
int *p,*q;
q=&(L.elem[i-1]);
for(p=&(L.elem[L.length-1]);p>=q;p–)
*(p+1)=*p;
*q=e;
L.length++;
return OK;
}
void Create(HashTable ha,SqList &L,int n,int m,int p) {
int i,address;
for (i=0;i<m;i++){
ha[i].key=0;
}
for (i=0;i<n;i++){
address=L.elem[i] % n;
if(ha[address].key){
do{
address=(address+1)%p;
}while(ha[address].key);
}
ha[address].key=L.elem[i];
}
}
int Search(HashTable ha,int p,int n,int k)
{ int i=0,address;
address=k % n;
while (ha[address].key!=0 && ha[address].key!=k)
{ i++;
address=(address+1) % p;
}
if (ha[address].key==k)
return address;
else
return -1;
}
void DispHT(HashTable ha,int n,int m)
{ int i;
printf(” 哈希表地址:\t”);
for (i=0;i<m;i++)
printf(” %3d”,i);
printf(” \n”);
printf(” 哈希表关键字:\t”);
for (i=0;i<m;i++)
if (ha[i].key==0 )
printf(” “);
else
printf(” %3d”,ha[i].key);
printf(” \n”);
}
void main(){
int key,n,i,m=13,p=13,j;
HashTable ha;
int num;
printf(“1:创建顺序表.2.输出创建的创建哈希表,3.输入想要查找的关键字\n”);
while(1){
printf(“输入选择\n”);
scanf(“%d”,&i);
switch(i){
case 1:
printf(“请输入元素个数:”);
scanf(“%d”,&num);
printf(“输入元素”);
for(i=1;i<=num;i++){
scanf(“%d”,&n);
InsertList_Sq(L,i,n);
}
break;
case 2:
printf(“输出创建的创建哈希表\n”);
Create( ha,L, num, m, p);
DispHT(ha,num,m);
break;
case 3:
printf(“输入关键字\n”);
scanf(“%d”,&key);
j=Search( ha, p,num, key);
if (j!=-1)
printf(” ha[%d].key=%d\n”,j,key);
else
printf(” 未找到%d\n”,key);
break;
default:
printf(“输入错误”);
break;
}
}
}
五、 程序运行情况(采用截图方式给出运行结果)
六、 小结(包括收获、心得体会、存在的问题及解决问题的方法、建议等)
在本次的实验中感觉最大的收获是更加熟悉了链表,在编写的查询过程前期一直出错,在复习了书本上的知识后解决了这个问题同时对相关的知识增加了了解,本次的实验不是很难,就是需要在查找关键字的时候需要了解是怎么样查找的,以及查找的相对的查找过程,还有哈希表的创建,其实就是对查找元素,创建索引表的过程。课后还是需要多加学习的。