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

news2025/2/23 7:18:02

文章目录

  • 1. 引言
  • 2. 实验原理
    • 2.1 散列表
    • 2.2 线性探测法
    • 2.3 冲突解决
  • 3. 实验内容
    • 3.1 实验题目
      • (一)输入要求
      • (二)输出要求
    • 3.2 算法实现
    • 3.3 代码整合
  • 4. 实验结果

1. 引言

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

2. 实验原理

2.1 散列表

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

2.2 线性探测法

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

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

2.3 冲突解决

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

3. 实验内容

3.1 实验题目

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

(一)输入要求

  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 算法实现

  1. 数据结构定义:

    typedef struct P{
        char *data;
        struct P *next;
    }P;
    

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

  2. 散列表数组:

    P* HEAD[32];
    

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

  3. Create 函数:

    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 计算数组的索引,将数据插入到对应的链表的头部。

  4. Output 函数:

    void Output()
    {
        P *p;
        int i;
        for (i = 0; i < 32; i++)
        {
            printf("HEAD: %2d", i);
            if (HEAD[i] != NULL)
            {
                p = HEAD[i];
                for (; p != NULL; p = p->next)
                    printf(" —>%s", p->data);
            }
            else printf("空");
            printf("\n");
        }
    }
    

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

  5. Find 函数:

    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。

  6. 主函数:

    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 代码整合

#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 %s\n",i,p->A);
}
void Output()
{
    P *p;
    int i;
    for(i=0;i<31;i++)
    {
    	printf("HEAD: %2d",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. 实验结果

在这里插入图片描述

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1253366.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity 场景切换

Unity场景切换可使用以下方法&#xff1a; 1、SceneManager.LoadScene()方法&#xff1a; using UnityEngine.SceneManagement;// 切换到Scene2场景 SceneManager.LoadScene("Scene2"); 2、使用SceneManager.LoadSceneAsync()方法异步加载场景&#xff0c;异步加载…

Python pandas对表格进行整行整列筛选、删除或修改,对特定值进行修改

Pandas库的使用 Pandas库&#xff1a;从入门到应用(二)–行列数据读写 Python数据处理工具 ——Pandas&#xff08;数据的预处理&#xff09; Pandas库有两个数据类型: Series, DataFrame Series 索引 一维数据DataFrame 行列索引 二维数据 DataFrame类型 DataFrame类型…

VMware虚拟机网络配置详解

vmware为我们提供了三种网络工作模式&#xff0c;它们分别是&#xff1a;Bridged&#xff08;桥接模式&#xff09;、NAT&#xff08;网络地址转换模式&#xff09;、Host-Only&#xff08;仅主机模式&#xff09; 打开vmware虚拟机&#xff0c;我们可以在选项栏的“编辑”下的…

U盘报错无法访问文件或目录损坏且无法读取

使用电脑打开U盘的部分文件时提示无法访问&#xff0c;文件或目录损坏且无法读取 报错内容如下图&#xff1a; 因为我这个U盘是那种双接口的 Type-C和USB&#xff0c;前段时间被我摔了一下 看网上说这种双接口的U盘USB接口容易坏掉 尝试在手机上使用OTG打开&#xff0c;先测试…

二叉树详讲(一)---完全二叉树、满二叉树、堆

1.树的概念及其结构 1.1树的概念 树是一种非线性数据结构&#xff0c;是一种种抽象数据类型&#xff0c;旨在模拟具有树状结构的节点之间的层次关系。一颗树由诺干个点和诺干条边组成。每棵树只有一个根节点&#xff0c;根节点向下延申又有子节点和叶子节点&#xff0c;叶子节…

Linux 命令vim(编辑器)

(一)vim编辑器的介绍 vim是文件编辑器&#xff0c;是vi的升级版本&#xff0c;兼容vi的所有指令&#xff0c;同时做了优化和延伸。vim有多种模式&#xff0c;其中常用的模式有命令模式、插入模式、末行模式&#xff1a;。 (二)vim编辑器基本操作 1 进入vim编辑文件 1 vim …

Kotlin学习——kt里的集合List,Set,Map List集合的各种方法之Int篇

Kotlin 是一门现代但已成熟的编程语言&#xff0c;旨在让开发人员更幸福快乐。 它简洁、安全、可与 Java 及其他语言互操作&#xff0c;并提供了多种方式在多个平台间复用代码&#xff0c;以实现高效编程。 https://play.kotlinlang.org/byExample/01_introduction/02_Functio…

【代码】考虑电解槽变载启停特性与阶梯式碳交易机制的综合能源系统优化调度matlab-yalmip-cplex/gurob

程序名称&#xff1a;考虑电解槽变载启停特性与阶梯式碳交易机制的综合能源系统优化调度 实现平台&#xff1a;matlab-yalmip-cplex/gurobi 代码简介&#xff1a;提出了一种考虑 变载启停特性的电解槽混合整数线性模型&#xff0c;根据电 氢负荷可以实时调整设备工作状态&…

android系统新特性——用户界面以及系统界面改进

用户界面改进 Android用户界面改进最明显的就是MD了。MD是Google于2014年推出的设计语言&#xff0c;它是一套完整的设计系统&#xff0c;包含了动画、样式、布局、组件等一系列与设计有关的元素。通过对这些行为的描述&#xff0c;让开发者设计出更符合目标的软件&#xff0c…

代码随想录算法训练营 ---第四十三天

前言&#xff1a; 今天同样是01背包问题&#xff0c;今天详细学习了背包问题在各种场景下的应用。今天一道也没做出来&#xff0c;有点废。好难啊&#xff01;就是思路不太清晰&#xff0c;不知道如何去做&#xff0c;看了题解后感觉原来如此&#xff0c;但是想不出来。今天做…

蓝桥杯官网算法赛(蓝桥小课堂)

问题描述 蓝桥小课堂开课啦&#xff01; 海伦公式&#xff08;Herons formula&#xff09;&#xff0c;也称为海伦-秦九韶公式&#xff0c;是用于计算三角形面积的一种公式&#xff0c;它可以通过三条边的长度来确定三角形的面积&#xff0c;而无需知道三角形的高度。 海伦公…

②⑩② 【读写分离】Sharding - JDBC 实现 MySQL读写分离[SpringBoot框架]

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ Sharding-JDBC Sharding-JDBC介绍使用 Shardin…

cmake install接口常用方式介绍

cmake install接口常用方式介绍 1 Synopsis2 Introduction2.1 DESTINATION <dir>2.2 PERMISSIONS <permission>...2.3 CONFIGURATIONS <config>...2.4 COMPONENT <component>2.5 EXCLUDE_FROM_ALL2.6 RENAME <name>2.7 OPTIONAL 3 Signatures4 E…

<JavaEE> 线程的五种创建方法 和 查看线程的两种方式

目录 一、线程的创建方法 1.1 继承 Thread -> 重写 run 方法 1.2 使用匿名内部类 -> 继承 Thread -> 重写 run 方法 1.3 实现 Runnable 接口 -> 重写 run 方法 1.4 使用匿名内部类 -> 实现 Runnable 接口 -> 重写 run 方法 1.5 使用 lambda 表达式 二…

Redis面试题:redis做为缓存,数据的持久化是怎么做的?两种持久化方式有什么区别呢?这两种方式,哪种恢复的比较快呢?

目录 面试官&#xff1a;redis做为缓存&#xff0c;数据的持久化是怎么做的&#xff1f; 面试官&#xff1a;这两种持久化方式有什么区别呢&#xff1f; 面试官&#xff1a;这两种方式&#xff0c;哪种恢复的比较快呢&#xff1f; 面试官&#xff1a;redis做为缓存&#xff…

Element-Plus 图标自动导入

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…

【RTP】RTPSenderAudio::SendAudio

RTPSenderAudio 可以将一个opus帧封装为rtp包进行发送,以下是其过程:RTPSenderAudio::SendAudio :只需要提供payload部分 创建RtpPacketToSend 并写入各个部分 填充payload部分 sender 本身分配全session唯一的twcc序号 if (!rtp_sender_->

终端移动性管理

联系前面所学的知识我们知道&#xff0c;移动性管理主要分为两大类&#xff1a;空闲状态下的移动性管理、连接状态下的移动性管理。我们今天来详细了解他们的工作原理~ 目录 移动性管理分类 1、空闲状态下的移动性管理 2、连接状态下的移动性管理 手机选择天线的原则 4G天…

香港站群服务器中1C/2C/4C/8C 的概念及区别

​  在选择香港站群服务器时&#xff0c;经常会看到1C、2C、4C和8C等不同的IP段。这些IP段代表了不同的子网掩码长度&#xff0c;也反映了服务器的IP地址数量和丰富性。 让我们来了解一下什么是IP段。IP段是指一组连续的IP地址&#xff0c;其中每个地址的前三个数字相同&…

从0到0.01入门 Webpack| 006.精选 Webpack面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…