简单讲解哈希表

哈希表(Hash Table),也被称为散列表,是一种高效的数据结构,它可以在O(1)的时间复杂度下完成插入、删除、查找等基本操作。哈希表是通过将关键字映射到一个固定大小的表中来实现的,这个映射函数被称为哈希函数。

什么是哈希函数

哈希函数是将任意长度的输入值(也称为“键”或“关键字”)映射为固定大小的输出值(也称为“哈希值”或“散列”)。哈希函数必须将不同的关键字映射到不同的哈希值中,从而使得关键字之间的比较可以转化为哈希值之间的比较,提高了查找效率。

常用的哈希函数有以下几种:

  1. 直接取模法:对哈希表的大小(通常为素数)取模,取模的结果作为哈希值。直接取模法的缺点是可能会使得某些哈希值的分布不均匀,影响了性能。
  2. 加权取模法:将关键字的每一位乘以不同的权值,再将所有结果相加,最后对哈希表的大小取模,取模的结果作为哈希值。加权取模法可以解决直接取模法产生的哈希冲突问题。
  3. MD5和SHA1:基于MD5和SHA1算法的哈希函数,可以生成128位和160位哈希值,具有较高的安全性和哈希性能。

哈希表的实现

哈希表的实现主要包含两个部分:哈希函数和哈希冲突的解决方法。

哈希函数

哈希函数的选择决定了哈希表的性能,好的哈希函数可以使哈希值的分布较为均匀,从而减少哈希冲突的概率。常用的哈希函数如下:

def hash_function(key, size):
    """
    直接取模法哈希函数
    :param key: 关键字
    :param size: 哈希表的大小
    :return: 哈希值
    """
    return key % size

哈希冲突的解决方法

哈希冲突指的是不同的关键字映射到同一个哈希值的情况。常用的哈希冲突解决方法有以下几种:

  1. 开放地址法:当出现哈希冲突时,依次查找下一个空的哈希桶,直到找到为止。
  2. 链地址法:将哈希桶中的元素存储在一个链表中,当出现哈希冲突时,在链表的末尾添加一个新元素。

哈希表的操作

插入操作

插入操作包含以下步骤:

  1. 计算关键字的哈希值;
  2. 根据哈希值找到对应的哈希桶;
  3. 判断哈希桶是否为空,如果为空,直接插入元素;
  4. 如果哈希桶不为空,根据哈希冲突的解决方法,找到下一个空闲的哈希桶,插入元素。
def insert(hash_table, key, value):
    # 计算哈希值
    hash_value = hash_function(key, len(hash_table))
    # 找到对应的哈希桶
    bucket = hash_table[hash_value]
    # 插入元素
    if not bucket:
        hash_table[hash_value] = [(key, value)]
    else:
        for i in range(len(bucket)):
            if bucket[i][0] == key:
                bucket[i] = (key, value)
                break
        else:
            bucket.append((key, value))

删除操作

删除操作比插入操作稍微复杂一些,因为需要考虑到哈希冲突。

删除操作包含以下步骤:

  1. 计算关键字的哈希值;
  2. 根据哈希值找到对应的哈希桶;
  3. 在哈希桶中查找是否存在关键字对应的元素;
  4. 如果存在,删除元素,如果不存在,返回错误提示。
def delete(hash_table, key):
    # 计算哈希值
    hash_value = hash_function(key, len(hash_table))
    # 找到对应的哈希桶
    bucket = hash_table[hash_value]
    # 在哈希桶中查找元素
    if bucket:
        for i in range(len(bucket)):
            if bucket[i][0] == key:
                del bucket[i]
                return
    print(f"Key {key} not found.")

查找操作

查找操作和删除操作类似,也需要考虑到哈希冲突。

查找操作包含以下步骤:

  1. 计算关键字的哈希值;
  2. 根据哈希值找到对应的哈希桶;
  3. 在哈希桶中查找是否存在关键字对应的元素;
  4. 如果存在,返回对应的值,如果不存在,返回错误提示。
def search(hash_table, key):
    # 计算哈希值
    hash_value = hash_function(key, len(hash_table))
    # 找到对应的哈希桶
    bucket = hash_table[hash_value]
    # 在哈希桶中查找元素
    if bucket:
        for i in range(len(bucket)):
            if bucket[i][0] == key:
                return bucket[i][1]
    print(f"Key {key} not found.")

示例说明

示例一

假设我们需要存储学生的姓名和对应的成绩信息,我们可以选择使用哈希表来实现。以下是实现的代码:

hash_table = [None] * 100

def add_student(name, score):
    insert(hash_table, name, score)

def get_score(name):
    return search(hash_table, name)

在上面的代码中,我们使用了一个长度为100的哈希表来存储学生信息,每个元素的格式为(key, value),其中key为学生的姓名,value为对应的成绩。我们通过调用insert函数来向哈希表中添加学生信息,通过调用search函数来查找学生信息。

示例二

假设我们需要存储一些网站的URL地址和对应的IP地址信息,我们可以选择使用哈希表来实现。以下是实现的代码:

hash_table = [None] * 100

def add_url(url, ip):
    insert(hash_table, url, ip)

def get_ip(url):
    return search(hash_table, url)

在上面的代码中,我们使用了一个长度为100的哈希表来存储URL地址和对应的IP地址信息,每个元素的格式为(key, value),其中key为URL地址,value为对应的IP地址。我们通过调用insert函数来向哈希表中添加URL地址和对应的IP地址信息,通过调用search函数来查找URL对应的IP地址。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:简单讲解哈希表 - Python技术站

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

相关文章

  • 如何使用C语言实现平衡二叉树数据结构算法

    使用C语言实现平衡二叉树数据结构算法可以分为以下几个步骤: 第一步:了解平衡二叉树 平衡二叉树是一种二叉搜索树,它具有以下特点: 高度平衡:每个节点的左右子树的高度差不能超过1。 有序性:对于任意一个节点,它的左子树中的所有节点都小于它,它的右子树中的所有节点都大于它。 平衡二叉树的优点在于它的查找、插入和删除操作都可以在O(log n)的时间内完成,比较快…

    数据结构 2023年5月17日
    00
  • Java数据结构之线段树的原理与实现

    Java数据结构之线段树的原理与实现 什么是线段树 线段树是一种基于分治思想的数据结构,它可以用来解决各种区间查询问题,例如区间求和、最大值、最小值等等。在算法竞赛和数据结构课程中,线段树被广泛应用,是一种非常实用的数据结构。 线段树的基本原理 线段树是一种二叉树,它的每个节点包含一个区间,叶子节点表示区间中的单个元素,非叶子节点表示区间的合并。 线段树的建…

    数据结构 2023年5月17日
    00
  • 【ACM算法竞赛日常训练】DAY5题解与分析【储物点的距离】【糖糖别胡说,我真的不是签到题目】| 前缀和 | 思维

    DAY5共2题: 储物点的距离(前缀和) 糖糖别胡说,我真的不是签到题目(multiset,思维) ? 作者:Eriktse? 简介:19岁,211计算机在读,现役ACM银牌选手?力争以通俗易懂的方式讲解算法!❤️欢迎关注我,一起交流C++/Python算法。(优质好文持续更新中……)?? 原文链接(阅读原文获得更好阅读体验):https://www.eri…

    算法与数据结构 2023年4月18日
    00
  • Java集合和数据结构排序实例详解

    Java集合和数据结构排序实例详解 作为Java程序员,集合和数据结构是我们经常会用到的工具,其中排序是其中非常重要的一环。本文将为大家详细介绍Java中集合和数据结构排序的实例。 Java集合排序 在Java中,集合排序通常使用Collections工具类来完成。Collections提供了多种排序算法,包括插入排序、选择排序、归并排序等等。例如,下面的示…

    数据结构 2023年5月17日
    00
  • Java 数据结构与算法系列精讲之哈希算法实现

    Java 数据结构与算法系列精讲之哈希算法实现 什么是哈希算法? 哈希算法是一种能将任意长度的消息压缩到某一固定长度的消息摘要的算法。 通过哈希算法,我们可以将一个任意的大数据量压缩成一段固定长度的数据,这个数据的长度通常比较小,相对于原数据的大小来说,要小得多。哈希算法的压缩特性使得它经常用来进行信息摘要、数据校验、唯一识别等功能,可以很大程度上提高数据的…

    数据结构 2023年5月17日
    00
  • C语言数据结构之堆、堆排序的分析及实现

    C语言数据结构之堆、堆排序的分析及实现 什么是堆 堆(Heap)是一种特殊的树形数据结构,它满足两个条件: 堆是一棵完全二叉树; 堆中任意节点的值总是不大于/不小于其子节点的值。 如果父节点的值不大于所有子节点的值,此堆称为小根堆,又称为最小堆。如果父节点的值不小于所有子节点的值,此堆称为大根堆,又称为最大堆。 堆通常可以使用数组来实现,具体实现方法是将堆的…

    数据结构 2023年5月17日
    00
  • Redis五种数据结构在JAVA中如何封装使用

    Redis 是一款高性能的键值存储数据库,支持五种不同的数据结构:字符串(String)、哈希(Hash)、列表(List)、集合(Set)和有序集合(Sorted Set)。在Java中使用Redis需要封装对应的数据结构,本文将详细介绍如何封装Redis的五种数据结构。 封装Redis字符串数据结构 Redis字符串数据结构对应Java中的String类…

    数据结构 2023年5月17日
    00
  • C语言数据结构之单链表的查找和建立

    C语言数据结构之单链表的查找和建立 什么是单链表? 单链表是一种常见的数据结构,是由若干个节点(Node)组成的链式结构,每个节点存储着链表中的元素和指向下一个节点的指针。 单链表的优点是插入、删除元素简单,但是查找元素比较困难。 在C语言中,我们可以使用结构体来定义一个节点: struct ListNode { int val; struct ListNo…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部