当前位置: 首页 > news >正文

C语言实现哈希搜索算法

一、哈希搜索算法原理

哈希搜索,也叫散列查找,是一种通过哈希表(散列表)实现快速查找目标元素的算法。哈希搜索算法通常适用于需要快速查找一组数据中是否存在某个元素的场景,其时间复杂度最高为 O(1),而平均情况下的时间复杂度通常相当接近 O(1),因此在实际应用中具有很高的效率和性能。

哈希搜索的核心思想是使用哈希函数将数据映射到一个哈希表中的某个位置,以便在需要查找时快速定位数据的位置,并进行数据访问。在理想情况下,不同的元素可以被映射到哈希表的不同位置,从而实现快速查找;但是在实际应用中,由于哈希函数的不完美或者数据的特殊分布等原因,不同的元素可能会被映射到相同的位置,这就会导致哈希碰撞(Hash Collision)的问题。

解决哈希碰撞问题的方法有很多,最常见的两种是拉链法和线性探测法:

  • 拉链法(Chaining):使用一个数组存储整个哈希表,每个数组元素都是一个链表的头指针,具有相同哈希值的元素会被链接到同一个链表上。当需要查找某个元素时,首先计算出该元素的哈希值,并定位到对应的链表上,然后遍历该链表寻找目标元素。

  • 线性探测法(Linear Probing):使用一个数组存储整个哈希表,在发生哈希碰撞时,从当前位置开始向后依次查找第一个空闲的位置,并将元素插入到该位置中,当需要查找某个元素时,首先计算出该元素的哈希值,并定位到对应的位置,如果该位置为空,则说明目标元素不存在于哈希表中;否则,如果该位置存储的元素与目标元素相同,则直接返回;否则,就继续向后查找直到找到目标元素或者遇到空位为止。

总的来说,哈希搜索是一种简单而高效的查找算法,但是它的实现涉及到许多细节问题,需要根据不同的应用场景和数据特征来选择最适合的哈希函数和哈希表结构,以保证其正常运行和高效性能。

二、哈希查找算法的C语言实现

下面是哈希查找算法的C语言实现示例:

#include <stdio.h>
#include <stdlib.h>
#define TABLE_SIZE 100 // 哈希表的大小
// 定义哈希表节点结构体
typedef struct Node {int key; // 节点键值int value; // 节点存储的值struct Node* next; // 指向下一个节点的指针
} Node;
// 创建一个哈希表并返回指针
Node** createHashTable() {Node** hashTable = (Node**) malloc(sizeof(Node*) * TABLE_SIZE);for (int i = 0; i < TABLE_SIZE; i++) {hashTable[i] = NULL;}return hashTable;
}
// 计算节点在哈希表中的下标
int getHashIndex(int key) {return key % TABLE_SIZE;
}
// 在哈希表中查找指定键值的节点,并返回该节点的指针
Node* findNode(Node** hashTable, int key) {int index = getHashIndex(key);Node* node = hashTable[index];while (node != NULL) {if (node->key == key) {return node;}node = node->next;}return NULL; // 没有找到节点,返回NULL
}
// 插入一个节点到哈希表中
void insertNode(Node** hashTable, int key, int value) {int index = getHashIndex(key);Node* node = hashTable[index];while (node != NULL) {if (node->key == key) {node->value = value;return;}node = node->next;}Node* new_node = (Node*) malloc(sizeof(Node));new_node->key = key;new_node->value = value;new_node->next = hashTable[index];hashTable[index] = new_node;
}
// 从哈希表中删除指定键值的节点
void deleteNode(Node** hashTable, int key) {int index = getHashIndex(key);Node* node = hashTable[index];Node* prev = NULL;while (node != NULL) {if (node->key == key) {if (prev == NULL) {hashTable[index] = node->next;} else {prev->next = node->next;}free(node);return;}prev = node;node = node->next;}
}
int main() {// 创建哈希表Node** hashTable = createHashTable();// 向哈希表中插入若干个节点insertNode(hashTable, 1, 2);insertNode(hashTable, 2, 4);insertNode(hashTable, 3, 6);// 查找节点并输出结果Node* node = findNode(hashTable, 2);if (node != NULL) {printf("键值为 %d 的节点的值为 %d\n", node->key, node->value);} else {printf("没有找到键值为 2 的节点\n");}// 删除节点并输出结果deleteNode(hashTable, 1);node = findNode(hashTable, 1);if (node != NULL) {printf("键值为 %d 的节点的值为 %d\n", node->key, node->value);} else {printf("没有找到键值为 1 的节点\n");}return 0;
}

上述代码中,我们定义了 Node 结构体表示哈希表的节点,包含了键值 key、存储值 value 和指向下一个节点的指针 next。其中 createHashTable 函数用来创建一个新的哈希表,getHashIndex 函数用来计算节点在哈希表中的下标,findNode 函数用来在哈希表中查找指定键值的节点,insertNode 函数用来将新节点插入到哈希表中,deleteNode 函数用来删除哈希表中指定键值的节点。

在主函数中,我们首先创建了一个新的哈希表,然后向哈希表中插入若干个节点,接着查找键值为2的节点并输出结果,最后删除键值为1的节点并输出结果。

需要注意的是,哈希表的实现涉及到很多细节问题,比如哈希函数、冲突解决方法等,如果没有特殊需求,可以使用已经实现好的哈希表库,例如C++ STL库中的 unordered_map 类。

相关文章:

C语言实现哈希搜索算法

一、哈希搜索算法原理 哈希搜索&#xff0c;也叫散列查找&#xff0c;是一种通过哈希表&#xff08;散列表&#xff09;实现快速查找目标元素的算法。哈希搜索算法通常适用于需要快速查找一组数据中是否存在某个元素的场景&#xff0c;其时间复杂度最高为 O(1)&#xff0c;而平…...

MySQL卸载并重装指定版本

MySQL卸载并重装制定版本 学习新的项目&#xff0c;发现之前的Navicat已经失去了与现有MySQL的链接&#xff0c;而且版本也不适合&#xff0c;为了少走弯路&#xff0c;准备直接重装相应版本的MySQL 卸载现有MySQL 停止windows的MySQL服务&#xff0c;【windowsR】打开运行框…...

文件IO编程 1 2

头文件包含路径 linux 操作系统分为两大空间&#xff1a;用户空间和内核空间 这样划分&#xff0c;是为了保护内核的核心组件&#xff0c;不被轻易访问和修改 系统调用&#xff1a;安全的访问内核空间 其核心是&#xff1a;函数API&#xff08;API&#xff1a;用户编程接口&…...

Java后端框架模块整合

提示&#xff1a;使用Java后端开发框架能够提高开发效率、代码质量&#xff0c;提升可扩展性&#xff0c;降低开发成本和易于维护。 文章目录 前言MyBatis 框架知识Spring 框架知识SpringMVC 框架知识SpringBoot 框架知识 前言 提示&#xff1a;这里可以添加本文要记录的大概内…...

17 synchronized关键字使用 synchronized方法、synchronized块

synchronized方法、synchronized块 线程的同步不安全的线程示例1&#xff1a;示例2示例3 synchronized方法、synchronized块 线程的同步 并发&#xff1a;同一个对象被多个线程同时操作。 解决方案&#xff1a;让多个线程排队操作对象。 使用队列和锁解决多线程的并发问题。 同…...

django-基本环境配置

文章目录 django 环境安装1. 安装环境1.1 安装 Python (配置虚拟环境)1.1.1 步骤 1.2 Conda配置环境参考 django 环境安装 1. 安装环境 1.1 安装 Python (配置虚拟环境) 由于国外源速度慢&#xff0c;可以pip添加清华源 pip config set global.index-url https://pypi.tuna.…...

Springboot 实践(4)swagger-ui 测试controller

前文项目操作&#xff0c;完成了项目的创建、数据源的配置以及数据库DAO程序的生成与配置。此文讲解利用swagger-ui界面&#xff0c;测试生成的数据库DAO程序。目前&#xff0c;项目swagger-ui界面如下&#xff1a; 以”用户管理”为例&#xff0c;简单讲述swagger-ui测试数据库…...

PHP实践:分布式场景下的Session共享解决方案实现

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责…...

07 - 查看、创建、切换和删除分支

查看所有文章链接&#xff1a;&#xff08;更新中&#xff09;GIT常用场景- 目录 文章目录 1. 查看分支2. 创建和切换分支3. 删除分支 1. 查看分支 git branch -va2. 创建和切换分支 第一种&#xff1a; 创建分支&#xff1a; git branch new_branch切换分支&#xff1a; …...

【SpringBoot】89、SpringBoot中使用@Transactional进行事务管理

事务是一组组合成逻辑工作单元的操作,虽然系统中可能会出错,但事务将控制和维护事务中每个操作的一致性和完整性。 1、SpringBoot 引用说明 新建的 Spring Boot 项目中,一般都会引用 spring-boot-starter 或者 spring-boot-starter-web,而这两个起步依赖中都已经包含了对…...

两天入门Linux、搭建Spring环境 第一天

一、Linux简介 1.什么是Linux 一个操作系统&#xff0c;未来公司里面会用到、接触的新操作系统。 2.为什么学Linux (1)个人职务需要&#xff0c;肯定会接触到Linux (2)职业发展&#xff0c;以后的发展肯定需要掌握Linux的许多使用方法 3.学哪些内容 (1)Linux基本介绍 (2)…...

OpenCV实例(九)基于深度学习的运动目标检测(一)YOLO运动目标检测算法

基于深度学习的运动目标检测&#xff08;一&#xff09; 1.YOLO算法检测流程2.YOLO算法网络架构3.网络训练模型3.1 训练策略3.2 代价函数的设定 2012年&#xff0c;随着深度学习技术的不断突破&#xff0c;开始兴起基于深度学习的目标检测算法的研究浪潮。 2014年&#xff0c;…...

CI/CD流水线实战

不知道为什么&#xff0c;现在什么技术都想学&#xff0c;因为我觉得我遇到了技术的壁垒&#xff0c;大的项目接触不到&#xff0c;做的项目一个字辣*。所以&#xff0c;整个人心浮气躁&#xff0c;我已经得通过每天的骑行和长跑缓解这种浮躁了。一个周末&#xff0c;我再次宅在…...

详解配置交换机多生成树MSTP+VRRP 的典型组网

详解配置交换机多生成树MSTPVRRP 的典型组网 组网&#xff1a; 1. 这是一个由三台交换机组成的倒三角型二层交换网络&#xff1b;网络中有4个VLAN&#xff1a;10、20、30、40&#xff1b;接口编号如图所示&#xff1b;SW3为接入层交换机&#xff0c;SW1、SW2为汇聚层交换机&am…...

二.net core 自动化发布到docker (Jenkins安装之后向导)

目录 ​​​​​​​​​​​​​​ 参考资料&#xff1a;https://www.jenkins.io/doc/book/installing/docker/#setup-wizard Post-installation setup wizard.(安装后安装向导) 基于上一篇文章安装&#xff0c;在安装并运行Jenkins&#xff08;不包括使用Jenkins Opera…...

【设计模式——学习笔记】23种设计模式——解释器模式Interpreter(原理讲解+应用场景介绍+案例介绍+Java代码实现)

案例引入 通过解释器模式来实现四则运算&#xff0c;如计算ab-c的值&#xff0c;具体要求 先输入表达式的形式&#xff0c;比如abc-de&#xff0c;要求表达式的字母不能重复在分别输入a,b,c,d,e的值最后求出结果 传统方案 编写一个方法&#xff0c;接收表达式的形式&#xf…...

【计算机网络】——数据链路层

二、组帧 1、字符计数法 帧头部使用一个字符来表示帧的大小(包括第一个计数字符) &#xff08;此处一字符一个字节&#xff09; 2、字符填充收尾定界法 特定字符来定界帧的首和尾。若帧中数据段出现等同于特定字符的字符内容&#xff0c;前置一个转义字符。(类似于正则表达…...

数据结构:栈和队列(超详细)

目录 ​编辑 栈&#xff1a; 栈的概念及结构&#xff1a; 栈的实现&#xff1a; 队列&#xff1a; 队列的概念及结构&#xff1a; 队列的实现&#xff1a; 扩展知识&#xff1a; 以上就是个人学习线性表的个人见解和学习的解析&#xff0c;欢迎各位大佬在评论区探讨&#…...

AI项目二:基于mediapipe的虚拟鼠标控制

若该文为原创文章&#xff0c;转载请注明原文出处。 一、项目介绍 由于博主太懒&#xff0c;mediapipe如何实现鼠标控制的原理直接忽略&#xff0c;最初的想法是想控制摄像头识别手指控制鼠标&#xff0c;达到播放电影的效果。基本上效果也是可以的。简单的说是使用mediapipe检…...

EVE-NG 隐藏没有镜像的模板

eve-ng 默认情况下&#xff0c;在添加node时&#xff0c;会列出所有的模板&#xff0c;这样用着很不方便。 通过以下方式&#xff0c;可以使没有设备的模板不可见 cp /opt/unetlab/html/includes/config.php.distribution /opt/unetlab/html/includes/config.php 打开 config…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...