C++ 实现哈希表的实例

下面是“C++ 实现哈希表的实例”的攻略。

什么是哈希表?

哈希表是一种用于存储键值对的数据结构,它通过哈希函数将键映射为一个确定的桶,然后将键值对存储到对应的桶中。哈希表的主要优势是能够支持快速的插入、查找和删除操作,因为它的查找时间是常数级别的,即 O(1)。

实现哈希表的基本步骤

在 C++ 中实现哈希表的基本步骤如下:

  1. 定义哈希函数:通常情况下,哈希函数会将键转化为一个整数值。可以使用 C++11 新增的 std::hash 及其特化模板来实现哈希函数,也可以自己定义哈希函数。
  2. 定义哈希表的数据结构:哈希表通常由一个数组和一个哈希函数组成,在数组中存储键值对。每个键值对是一个链表中的节点,用于解决哈希值冲突的问题。
  3. 实现哈希表的插入、查找和删除操作:哈希表的操作与链表非常类似,不同的是需要先对键进行哈希,然后找到对应的桶。

具体步骤我们将在下面的示例中说明。

示例1:使用 C++11 的 std::hash 实现哈希表

下面是一个使用 C++11 的 std::unordered_map 实现哈希表的示例。

#include <iostream>
#include <unordered_map>

int main()
{
    // 创建一个 unordered_map 容器,用于存储字符串和对应的整数值
    std::unordered_map<std::string, int> hashmap;

    // 添加键值对
    hashmap["hello"] = 1;
    hashmap["world"] = 2;
    hashmap["test"] = 3;

    // 查找键对应的值
    std::cout << hashmap["hello"] << std::endl;

    // 删除键值对
    hashmap.erase("test");

    return 0;
}

上面的代码中,我们先使用 std::unordered_map 定义了一个哈希表,它包含 std::string 类型的键和 int 类型的值。然后我们使用 [] 操作符向哈希表中添加键值对,并使用 [] 操作符找到键对应的值。最后使用 erase 函数删除键值对。这些操作与使用普通的数组非常相似,而且它们的时间复杂度也是常数级别的。

示例2:手动实现哈希表

下面是一个手动实现哈希表的示例,其中我们使用了一个简单的哈希函数和链表来解决哈希冲突的问题。

#include <iostream>
#include <string>

const int TABLE_SIZE = 128;

class Node
{
public:
    std::string key;
    int value;
    Node* next;

    Node(const std::string& key, int value) :
        key(key), value(value), next(nullptr)
    {}
};

class HashMap
{
private:
    Node** table;
    std::hash<std::string> hashFunc;

public:
    HashMap()
    {
        table = new Node*[TABLE_SIZE];
        for (int i = 0; i < TABLE_SIZE; i++)
        {
            table[i] = nullptr;
        }
    }

    ~HashMap()
    {
        for (int i = 0; i < TABLE_SIZE; i++)
        {
            Node* node = table[i];
            while (node != nullptr)
            {
                Node* temp = node;
                node = node->next;
                delete temp;
            }
        }
        delete[] table;
    }

    void put(const std::string& key, int value)
    {
        int index = hashFunc(key) % TABLE_SIZE;
        Node* node = table[index];

        if (node == nullptr)
        {
            table[index] = new Node(key, value);
        }
        else
        {
            while (node != nullptr)
            {
                if (node->key == key)
                {
                    node->value = value;
                    return;
                }
                else if (node->next == nullptr)
                {
                    node->next = new Node(key, value);
                    return;
                }
                node = node->next;
            }
        }
    }

    int get(const std::string& key)
    {
        int index = hashFunc(key) % TABLE_SIZE;
        Node* node = table[index];
        while (node != nullptr)
        {
            if (node->key == key)
            {
                return node->value;
            }
            node = node->next;
        }
        return -1;
    }

    void remove(const std::string& key)
    {
        int index = hashFunc(key) % TABLE_SIZE;
        Node* node = table[index];
        if (node == nullptr)
        {
            return;
        }
        else if (node->key == key)
        {
            table[index] = node->next;
            delete node;
        }
        else
        {
            while (node->next != nullptr)
            {
                if (node->next->key == key)
                {
                    Node* temp = node->next;
                    node->next = node->next->next;
                    delete temp;
                    return;
                }
                node = node->next;
            }
        }
    }
};

int main()
{
    // 创建一个哈希表,用于存储字符串和对应的整数值
    HashMap hashmap;

    // 添加键值对
    hashmap.put("hello", 1);
    hashmap.put("world", 2);
    hashmap.put("test", 3);

    // 查找键对应的值
    std::cout << hashmap.get("hello") << std::endl;

    // 删除键值对
    hashmap.remove("test");

    return 0;
}

上面的代码中,我们手动实现了哈希表的插入、查找和删除操作。具体来说,我们使用 std::hash 实现了一个简单的哈希函数,将字符串转化为一个整数并求模,然后根据这个整数找到对应的桶。每个桶是一个链表,用于存储键值对。我们实现了 put、get 和 remove 函数来完成哈希表的插入、查找和删除操作,这些操作的时间复杂度都是常数级别的。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++ 实现哈希表的实例 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • Java基础之super关键字浅析

    让我来为你讲解Java基础中的super关键字。 什么是super关键字 在Java中,super是一个关键字,用于表示父类对象的引用。使用super关键字可以方便地调用父类的构造方法、属性和方法,也可以用来解决子类与父类存在同名方法或属性的问题。 super关键字的语法 下面是使用super关键字的两种形式:- 调用父类构造方法: java super(参…

    other 2023年6月27日
    00
  • vue中注册组件的两种方式详解(全局注册&& 局部注册)

    Vue中注册组件的两种方式详解(全局注册 && 局部注册) 在Vue中,我们可以使用两种方式来注册组件:全局注册和局部注册。这两种方式都有各自的优势和用途。 全局注册 全局注册是将组件注册为全局可用的,可以在任何Vue实例中使用。下面是全局注册组件的步骤: 在Vue实例之前,使用Vue.component方法来注册组件。 在组件注册时,需要指…

    other 2023年8月19日
    00
  • Remix集成antd和pro-components的过程示例

    Remix集成antd和pro-components的过程示例攻略 Remix是一个基于React的现代化JavaScript框架,它提供了一种简单而强大的方式来构建Web应用程序。在本攻略中,我们将详细讲解如何将antd和pro-components集成到Remix应用程序中。 步骤一:安装依赖 首先,我们需要安装一些必要的依赖项。打开终端并导航到你的Re…

    other 2023年9月7日
    00
  • 基于Android在布局中动态添加view的两种方法(总结)

    当使用Android开发时,有两种常见的方法可以在布局中动态添加View。下面是这两种方法的详细解释和示例说明: 方法一:使用Java代码动态添加View 首先,在XML布局文件中定义一个容器,例如LinearLayout或RelativeLayout。 <LinearLayout android:id=\"@+id/container\&q…

    other 2023年8月25日
    00
  • java入门:基础算法之二进制转换为十进制

    Java入门:基础算法之二进制转换为十进制 在Java编程中,经常需要进行二进制和十进制之间的转换。本文将介绍如何将二进制转换为十进制,并提供两个示例说明,以帮助您更好地理解和应用这些技术。 二进制转换为十进制的方法 将进制转换为十进制的方法是将每个二进制位乘以2的幂次方,然后将结果相加。例如,二进制数1011转换为十进制数的计算方法如下: 1*2^3 + …

    other 2023年5月7日
    00
  • Linux kernel模块管理相关详解

    Linux kernel模块管理相关详解 本文将详细介绍Linux kernel模块管理相关内容,包括模块是什么、如何编写、如何编译、如何加载和卸载模块等。 什么是Linux kernel模块 Linux kernel模块是一段代码,它可以动态地加载和卸载到Linux内核中,以增加内核的功能。模块可以在不影响现有内核的情况下加入内核,并最终集成到内核中。通过…

    other 2023年6月27日
    00
  • win32下的命令行集合

    win32下的命令行集合 Win32下的命令行集合是指Windows操作系统中提供的命令行工具,通过这些工具用户可以进行系统管理、文件操作、网络配置等各种任务。下面介绍一些常用的命令行工具及其用法。 命令行工具列表 以下是一些常用的命令行工具及其用途: cmd.exe: 用于在Windows操作系统中启动命令提示符窗口。 dir: 用于列出当前目录中的所有文…

    other 2023年6月26日
    00
  • Process Explorer使用图文教程

    Process Explorer是一款由微软公司开发的免费系统监控工具,可以显示系统中所有进程的详细信息,包括进程的CPU、内存、磁盘和网络使用情况等。本文将详细讲解Process Explorer的使用方法,包括下载、安装、界面介绍、功能说明和示例说明。 下载和安装 Process Explorer可以从微软官网免费下载,下载地址为:https://doc…

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