【数据结构实验】查找(一)基于散列表的查找算法

2024-07-30 10:54:26 浏览数 (2)

1. 引言

本实验将通过C语言实现基于散列表的查找算法

2. 实验原理

2.1 散列表

  散列表(Hash Table)是一种常见的数据结构,通过使用哈希函数将关键字映射到一个固定大小的数组中。这样可以通过计算关键字的哈希值,将其直接映射到数组的索引,实现快速的数据查找。

2.2 线性探测法

  哈希函数是散列表中的关键组成部分,它接受一个关键字并返回其在数组中的索引。一个好的哈希函数应该具有以下特性:

  • 一致性:对于相同的输入,始终返回相同的输出。
  • 均匀性:哈希值在数组范围内均匀分布,避免冲突。

2.3 冲突解决

  由于哈希函数的输出范围有限,不同的关键字可能映射到相同的索引位置,造成冲突。冲突解决的方法有很多,包括链地址法、开放地址法等。

3. 实验内容

3.1 实验题目

   编写算法构造教材图 8.47 的拉链表,输出散列表每个槽对应的单链表,并编程计算查找成功时的平均查找长度。

(一)输入要求
代码语言:javascript复制
  char *A[30]={
        "THE","OF","AND","TO","A",
        "IN","THAT","IS","WAS","HE",
        "FOR","IT","WITH","AS","HIS",
        "ON","BE","AT","BY","I",
        "THIS","HAD","NOT","ARE","BUT",
        "FROM","OR","HAVE","AN","THEY",
        };
    int B[30]={
        25,9,11,27,1,7,9,26,5,13,
        27,29,2,18,18,1,7,21,27,9,
        6,13,21,22,3,22,29,26,15,0
        };
(二)输出要求
  1. 输出散列表每个槽 HEADi对应的单链表;
  2. 编程计算并输出查找成功时的平均查找长度。

3.2 算法实现

数据结构定义:

代码语言:javascript复制
typedef struct P{
    char *data;
    struct P *next;
}P;

   定义了一个结构体 P,包含了一个字符串类型的数据域 data 和一个指向下一个节点的指针 next,用于构建散列表的基本节点结构。

散列表数组:

代码语言:javascript复制
P* HEAD[32];

   数组 HEAD中的每个元素是一个指向链表头部的指针~这是一个散列表,共有 32 个槽(桶)。

Create 函数:

代码语言:javascript复制
void Create(char *A, int K)
{
    int i = K;
    P *p = (P*)malloc(sizeof(P));
    p->data = A;
    p->next = HEAD[i];
    HEAD[i] = p;
}

Create 函数用于在散列表中插入数据。给定字符串 A 和整数 K,根据 K 计算数组的索引,将数据插入到对应的链表的头部。

Output 函数:

代码语言:javascript复制
void Output()
{
    P *p;
    int i;
    for (i = 0; i < 32; i  )
    {
        printf("HEAD: -", i);
        if (HEAD[i] != NULL)
        {
            p = HEAD[i];
            for (; p != NULL; p = p->next)
                printf(" —>%s", p->data);
        }
        else printf("空");
        printf("n");
    }
}

Output 函数用于输出整个散列表的内容。对于每个槽,输出链表中的所有节点。

Find 函数:

代码语言:javascript复制
int Find(char *ch, int K){
    int time = 0;
    int i = K;
    P *p = HEAD[i];
    while (p){
        time  ;
        if (p->data == ch) 
            return time;
        p = p->next;
    }
    return 0;
}

Find 函数用于在散列表中查找特定数据。给定字符串 ch 和整数 K,根据 K 计算数组的索引,然后在对应链表中查找字符串。如果找到,返回查找次数;否则,返回 0。

主函数:

代码语言:javascript复制
int main()
{
    // 数据初始化
    char *A[30] = { /* ... */ };
    int B[30] = { /* ... */ };

    int i, f, times = 0;
    float sum = 0;

    // 创建散列表
    for (i = 0; i < 30; i  ){
        Create(A[i], B[i]);
    }

    // 输出散列表
    Output();

    // 查找并计算平均查找长度
    for (i = 0; i < 30; i  ){
        f = Find(A[i], B[i]);
        if (f){
            times  ;
            sum  = f;
        }
    }
    
    printf("查找成功时的平均查找长度为:%f", sum / times);

    return 0;
}

3.3 代码整合

代码语言:javascript复制
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct P{
    char *data;
    struct P *next;
}P;
P* HEAD[32];
void Create(char *A,int K)
{
	int i=K;
    P *p=(P*)malloc(sizeof(P));
    p->data=A;
    p->next=HEAD[i];
    HEAD[i]=p;
   // printf("%d %sn",i,p->A);
}
void Output()
{
    P *p;
    int i;
    for(i=0;i<31;i  )
    {
    	printf("HEAD: -",i);
        if(HEAD[i]!=NULL)
        {
            p=HEAD[i];
            for(;p!=NULL;p=p->next)
                printf(" —>%s",p->data);
        }
        else printf("空");
		printf("n");
    }
}
int Find(char *ch,int K){
	int time=0;
	int i=K;
	P *p=HEAD[i];
	while(p){
		time  ;
		if(p->data==ch) return time;
		p=p->next;
	}
	return 0;
}
int main()
{
    char *A[30]={
	"THE","OF","AND","TO","A",
	"IN","THAT","IS","WAS","HE",
	"FOR","IT","WITH","AS","HIS",
	"ON","BE","AT","BY","I",
	"THIS","HAD","NOT","ARE","BUT",
	"FROM","OR","HAVE","AN","THEY",
	};
	int B[30]={
	25,9,11,27,1,7,9,26,5,13,
	27,29,2,18,18,1,7,21,27,9,
	6,13,21,22,3,22,29,26,15,0
	};
    int i,f,times=0;
    float sum=0;
    for(i=0;i<30;i  ){
    	Create(A[i],B[i]);
	}
    Output();
    for(i=0;i<30;i  ){
    	f=Find(A[i],B[i]);
    	if(f){
    		//printf("查找成功");
    		times  ;
    		sum =f;
		}
    	//else  printf("查找失败");
	}
	printf("查找成功时的平均查找长度为:%f",sum/times);

    return 0;
}

4. 实验结果

代码语言:javascript复制
HEAD:  0 —>THEY
HEAD:  1 —>ON —>A
HEAD:  2 —>WITH
HEAD:  3 —>BUT
HEAD:  4空
HEAD:  5 —>WAS
HEAD:  6 —>THIS
HEAD:  7 —>BE —>IN
HEAD:  8空
HEAD:  9 —>I —>THAT —>OF
HEAD: 10空
HEAD: 11 —>AND
HEAD: 12空
HEAD: 13 —>HAD —>HE
HEAD: 14空
HEAD: 15 —>AN
HEAD: 16空
HEAD: 17空
HEAD: 18 —>HIS —>AS
HEAD: 19空
HEAD: 20空
HEAD: 21 —>NOT —>AT
HEAD: 22 —>FROM —>ARE
HEAD: 23空
HEAD: 24空
HEAD: 25 —>THE
HEAD: 26 —>HAVE —>IS
HEAD: 27 —>BY —>FOR —>TO
HEAD: 28空
HEAD: 29 —>OR —>IT
HEAD: 30空
查找成功时的平均查找长度为:1.466667

0 人点赞