C语言实现散列表(哈希Hash表)实例详解

下面我将为您详细讲解“C语言实现散列表(哈希Hash表)实例详解”的完整攻略。

概述

哈希(Hash)是一种能够快速定位存储位置的技术。哈希表(Hash Table)也叫散列表,是利用哈希函数(Hash Function)进行访问的数据结构。C语言中的哈希表主要分为两种:开放地址法和链表法。

开放地址法又分为线性探测法、二次探测法和双重散列法。本文主要介绍使用链表法实现哈希表的过程。

链表法将数组中的每个元素当作一个链表头,然后将同一个哈希值的元素储存在同一个链表中。

实现步骤

  1. 定义哈希表数据结构。哈希表主要由数组和哈希函数组成。
#define MAX_SIZE 100
typedef struct hash_node
{
    int key; //键值
    int value; //值
    struct hash_node *next; 
}HashNode; //哈希表的节点

typedef struct hash_table
{
    HashNode *hash_map[MAX_SIZE]; //哈希表数组
}HashTable; //哈希表

  1. 实现哈希函数。哈希函数的作用是将键值转换为对应的哈希值,以便于存储在哈希表中。
int hash_function(int key)
{
    return key % MAX_SIZE;
}
  1. 实现插入节点的函数。当哈希表中不存在对应的节点时,将新节点插入到对应的链表中。
void hash_insert(HashTable *ht, int key, int value)
{
    int index = hash_function(key); //计算哈希值

    HashNode *p = ht->hash_map[index];
    while (p != NULL)
    {
        if (p->key == key) //如果存在相同的键值
        {
            p->value = value; //更新值
            return;
        }
        p = p->next;
    }

    //如果不存在相同键值,则将新节点插入到链表头
    HashNode *new_node = (HashNode*)malloc(sizeof(HashNode));
    new_node->key = key;
    new_node->value = value;
    new_node->next = ht->hash_map[index];
    ht->hash_map[index] = new_node;
}
  1. 实现查找节点的函数。当哈希表中不存在对应的节点时,返回错误信息;否则返回对应节点的值。
int hash_search(HashTable *ht, int key)
{
    int index = hash_function(key); //计算哈希值

    HashNode *p = ht->hash_map[index];
    while (p != NULL)
    {
        if (p->key == key) //如果找到节点
        {
            return p->value; //返回节点的值
        }
        p = p->next;
    }

    //如果不存在指定的节点,返回错误信息
    return -1;
}
  1. 实现删除节点的函数。当哈希表中不存在对应的节点时,返回错误信息;否则删除指定节点。
int hash_delete(HashTable *ht, int key)
{
    int index = hash_function(key); //计算哈希值

    HashNode *p = ht->hash_map[index];
    HashNode *pre = p;

    while (p != NULL)
    {
        if (p->key == key) //如果找到节点
        {
            if (pre == p) //如果该节点是链表头
            {
                ht->hash_map[index] = p->next; //删除链表头
            }
            else //如果该节点不是链表头
            {
                pre->next = p->next; //删除该节点
            }
            free(p); //释放空间
            return 0;
        }
        pre = p;
        p = p->next;
    }

    //如果不存在指定的节点,返回错误信息
    return -1;
}

示例说明

示例1:使用哈希表实现简单的字典

#include <stdio.h>
#include "hash_table.h"

int main()
{
    HashTable ht;
    int key, value, choice;
    int ret;

    while(1) {
        printf("---------------------------\n");
        printf("请选择操作:\n");
        printf("1、插入\n2、查找\n3、删除\n0、退出\n");

        scanf("%d", &choice);
        switch(choice) {
            case 1:
                printf("请输入要插入的键值(key)和对应的值(value):\n");
                scanf("%d%d", &key, &value);
                hash_insert(&ht, key, value);
                break;
            case 2:
                printf("请输入要查找的键值(key):\n");
                scanf("%d", &key);
                ret = hash_search(&ht, key);
                if (ret == -1)
                    printf("不存在该节点\n");
                else
                    printf("该键值对应的值为:%d\n", ret);
                break;
            case 3:
                printf("请输入要删除的键值(key):\n");
                scanf("%d", &key);
                ret = hash_delete(&ht, key);
                if (ret == -1)
                    printf("不存在该节点\n");
                else
                    printf("删除成功\n");
                break;
            case 0:
                return 0;
            default:
                printf("请输入正确的操作\n");
                break;
        }
    }

    return 0;
}

示例2:使用哈希表实现统计字符串中每个字符出现的次数

#include <stdio.h>
#include <string.h>
#include "hash_table.h"

int main()
{
    char str[100];
    printf("请输入字符串:\n");
    scanf("%s", str);

    HashTable ht;
    memset(&ht, 0, sizeof(ht));

    for(int i=0; i<strlen(str); i++) {
        int key = str[i];
        int value = hash_search(&ht, key);

        if (value == -1) {
            hash_insert(&ht, key, 1);
        } else {
            hash_insert(&ht, key, value+1);
        }
    }

    for(int i=0; i<MAX_SIZE; i++) {
        HashNode *p = ht.hash_map[i];
        while(p != NULL) {
            printf("字符'%c'出现了%d次\n", p->key, p->value);
            p = p->next;
        }
    }

    return 0;
}

结束语

以上就是使用链表法实现哈希表的完整攻略,包含了定义哈希表数据结构、实现哈希函数、插入节点、查找节点和删除节点等过程。同时也给出了两个示例,可供参考。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言实现散列表(哈希Hash表)实例详解 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • 关于C语言中参数的传值问题

    关于C语言中参数的传值问题 在C语言中参数的传递方式有两种:传值(Call by Value)和传址(Call by Reference)。 传值(Call by Value) 对于传值方式,函数只能访问传递进来的参数的值,无法修改传递进来的参数本身。传递的是参数的复制品而不是原始参数。 以下是传值方式的示例代码: #include <stdio.h&…

    C 2023年5月23日
    00
  • Java内部类和异常类的概念以及使用

    Java内部类(Inner Class)是定义在其他类中的类。内部类具有比普通类更多的访问权限,可以访问其外部类的私有属性和方法。Java内部类可以分为四种类型:成员内部类、局部内部类、匿名内部类和静态内部类。 举个例子:假设有一个外部类叫做OuterClass,它有一个私有属性叫做privateVar,内部类叫做InnerClass。下面是一个成员内部类的…

    C 2023年5月23日
    00
  • C++函数返回值为对象时,构造析构函数的执行细节

    当C++函数返回一个对象时,编译器在底层会进行以下的操作: 为返回值对象分配内存空间 调用返回值对象的构造函数,初始化该对象 调用函数的代码,修改返回值对象的状态 返回控制权到调用函数的代码 调用返回值对象的析构函数,释放内存空间 下面是一个示例代码,演示了C++函数返回值为对象的情况: class Person { private: std::string…

    C 2023年5月22日
    00
  • JS实现简单的二元方程计算器功能示例

    下面我会详细讲解如何实现一个简单的二元方程计算器功能。 1.需求分析 首先,我们需要明确我们要实现什么功能。这个简单的二元方程计算器要能够接收用户输入的两个数值,然后进行加、减、乘、除运算,并将计算结果输出给用户。 2.实现步骤 2.1 创建HTML文件和JS文件 首先,我们需要创建一个HTML文件和一个JS文件。HTML文件用来布局和展示界面,JS文件用来…

    C 2023年5月22日
    00
  • c++中c_str()的用法示例

    下面是对于“c++中c_str()的用法示例”的完整攻略: 什么是c_str() c_str()是一个C++字符串类string的成员函数,用于将string类型字符串转换成C风格的字符串,即以’\0’结尾的字符数组。 c_str()函数的语法 c_str()函数的语法如下: const char* c_str() const noexcept; 该函数返回…

    C 2023年5月23日
    00
  • C++中关于互斥量的全面认知

    C++中的互斥量是多线程编程中实现同步的重要手段。以下是关于互斥量的全面认知攻略: 互斥量的基本概念 互斥量(Mutex)是一种同步工具,用于保护被多线程共享的资源(如共享内存)不被并发访问和修改,实现了资源的互斥访问。互斥量可以用于解决多线程环境中的竞争条件问题。 互斥量的使用 在C++中,互斥量是通过<mutex>头文件来使用。简单使用互斥量…

    C 2023年5月22日
    00
  • C++入门之基础语法学习教程

    当初编写C++入门之基础语法学习教程的目的是为了帮助初学者快速掌握C++的基础语法知识,确保他们能够顺利理解和编写简单的C++程序。下面将分为四步详细讲解攻略: 第一步:学习C++的基本语法 C++的基本语法包括变量定义、数据类型、运算符、控制语句和函数等,其中变量定义是C++程序必须要掌握的基础;数据类型可以构建不同类型的数据,可以帮助我们更好地处理数据;…

    C 2023年5月23日
    00
  • C++实现LeetCode(188.买卖股票的最佳时间之四)

    C++实现LeetCode(188.买卖股票的最佳时间之四)攻略 题目描述 给定一个数组 prices ,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。 注意: 你不能同时参与多笔交易(即,你必须在再次购买前出售掉之前的股票)。 示例1: 输入:k = 2, p…

    C 2023年5月22日
    00
合作推广
合作推广
分享本页
返回顶部