首页 > 编程语言 >哈希搜索算法及C语言实现

哈希搜索算法及C语言实现

时间:2023-06-14 22:32:55浏览次数:40  
标签:node Node 哈希 搜索算法 C语言 hashTable key 节点

一、哈希搜索算法原理

哈希搜索,也叫散列查找,是一种通过哈希表(散列表)实现快速查找目标元素的算法。哈希搜索算法通常适用于需要快速查找一组数据中是否存在某个元素的场景,其时间复杂度最高为 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 类。

标签:node,Node,哈希,搜索算法,C语言,hashTable,key,节点
From: https://blog.51cto.com/u_15903730/6481865

相关文章

  • [C语言/PTA] 学生成绩链表处理
    题目要求本题要求实现两个函数,一个将输入的学生成绩组织成单向链表;另一个将成绩低于某分数线的学生结点从链表中删除。函数接口定义:structstud_node*createlist();structstud_node*deletelist(structstud_node*head,intmin_score);函数createlist利用scanf从输入......
  • [C语言/PTA] 单链表结点删除
    题目要求本题要求实现两个函数,分别将读入的数据存储为单链表、将链表中所有存储了某给定值的结点删除。链表结点定义如下:structListNode{intdata;ListNode*next;};函数接口定义:structListNode*readlist();structListNode*deletem(structListNode*L,intm);......
  • [C语言/PTA] 建立学生信息链表
    题目要求本题要求实现一个将输入的学生成绩组织成单向链表的简单函数。函数接口定义:voidinput();该函数利用scanf从输入中获取学生的信息,并将其组织成单向链表。链表节点结构定义如下:structstud_node{intnum;/*学号*/charnam......
  • C/C++C语言课程设计[2023-06-14]
    C/C++C语言课程设计[2023-06-14]C语言课程设计要求1、每位同学按照指定的题目完成C语言课程设计,题目不能更换,每人1题,独立完成。上课时间同学们进入学习通课程(C语言课程设计)里签到,老师会有讲解检查。2、考核要求成绩组成考核/评价环节分值(或百分比)考核/评价细则平时成绩考勤、......
  • Dubbo负载均衡策略之 一致性哈希
    本文主要讲解了一致性哈希算法的原理以及其存在的数据倾斜的问题,然后引出解决数据倾斜问题的方法,最后分析一致性哈希算法在Dubbo中的使用。通过这篇文章,可以了解到一致性哈希算法的原理以及这种算法存在的问题和解决方案。一、负载均衡在这里引用dubbo官网的一段话——LoadBala......
  • java开发C语言编译器:jvm的return指令以及局部变量的操作
    jvm运行字节码时,代码的运行必须围绕两种数据结构,一种是堆栈,一种是队列,如果jvm执行某条指令时,该指令需要对数据进行操作,那么被操作的数据在指令执行前,必须要压倒堆栈上。如果堆栈上的数据需要暂时保持起来时,它就会被加载到局部变量队列上。java代码中,每个方法里面的局部变量包括函数......
  • java开发C语言解释器:数组元素的读取和赋值
    本节技术内容难度较大,请结合视频对代码的讲解和调试来理解本节内容:用java开发编译器一个成熟的编译器或解释器,要能够解析和执行目标语言开发的逻辑复杂的程序代码,我们用java开发的C语言解释器,能够执行用C语言开发的较为复杂的程序时,才称得上是合格的,从本节开始,我们致力于C语言解......
  • java开发系统内核:使用C语言开发系统应用程序
    更详细的讲解和代码调试演示过程,请参看视频用java开发C语言编译器更详细的讲解和代码调试演示过程,请参看视频如何进入google,算法面试技能全面提升指南如果你对机器学习感兴趣,请参看一下链接:机器学习:神经网络导论更详细的讲解和代码调试演示过程,请参看视频LinuxkernelHacker,......
  • java开发C语言编译器:JVM 的基本操作指令介绍及其程序运行原理
    更详细的讲解和代码调试演示过程,请参看视频用java开发C语言编译器更详细的讲解和代码调试演示过程,请参看视频如何进入google,算法面试技能全面提升指南如果你对机器学习感兴趣,请参看一下链接:机器学习:神经网络导论更详细的讲解和代码调试演示过程,请参看视频LinuxkernelHacker,......
  • java开发C语言编译器: return 语句的解释和执行
    在C语言程序中,很多函数并不是执行全部语句后,才从最底部返回的,大多数情况下,当某些条件成立时就可以通过return语句立即返回,而无需执行接下来的代码,本节,我们继续增强java开发的C语言解释器功能,使其能够处理return语句,完成本节代码后,我们的C语言解释器能够正常解析和执行下面的代码:in......