我的编程空间,编程开发者的网络收藏夹
学习永远不晚

哈希表的原理及实现代码

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

哈希表的原理及实现代码

哈希表可以表述为,是一种可以根据关键字快速查询数据的数据结构

一. 哈希表有哪些优点?

不论哈希表中数据有多少,增加,删除,改写数据的复杂度平均都是O(1),效率非常高

二. 实现哈希表

1. 哈希表原理

如果说每一个数据它都对应着一个固定的位置,那我们查找特定一个数据时,就可以直接查看这个数据对应的位置是否存在数据。一个形象的例子就是学生在教室中的位置,开学的时候,老师会给学生每一个人分配一个位置,而且不允许学生随便乱坐位置,以后老师要查看今天李刚同学有没有上课,直接看李刚同学的位置是不是有人就可以判断,没必要点了全班同学的名才可以知道李刚同学来了没有。

2. 实现简单的哈希表

根据上面的原理,首先,我们要分配一片空间用来存储我们数据,比如是一个空的数组

然后,有数据存进来的时候,按照特定规则得出这个数据在数组中的位置,将数据存进这个位置

我们就以存进一个整型数据为例,特定规则就是取余

根据计算出来的值,将这些数据放入对应的位置,我们的数组变为

我们已经把数据插入到了哈希表中,现在,我们要查找一个数据,只要按照取余规则计算出这个数据在数组中对应的位置,然后查看数组的这个位置,就可以取出这个数据了,比如我们要从哈希表中取出52,根据取余规则,52的计算出来的位置是8,数组中8这个位置是空的,52不在哈希表中,找不到52的数据;从哈希表中取出77,77计算出来的位置是0,数组中0这个位置有值,而且值就是77,从哈希表中取出77的值。

至此,我们知道实现了一个很简单的哈希表的原理,其实还存在很多问题,这个我们接下来讨论,这儿先把我们前面的一些概念用专业的术语替换一下,前面我们所说的特定规则,我们称之为哈希函数,用特定股则计算出来的值称之为哈希值。

3. 还存在哪些问题?

  1. 有可能两个数据通过哈希函数计算出来的哈希值有可能相等,比如77,88计算出来的位置值都是0

  2. 如果哈希表满了,该怎么扩容

第一个问题就是如何解决这种冲突

有开放定址法,链定址法,我们说一下开放定址法,就是将这个冲突的数据再重新计算一个空的位置,将其存进去,比如我们要存放88,哈希值是0,数组这个位置已经有值了,那我们再获取一个哈希值,比如在原哈希值的基础上加1,得到1,1的位置是空,我将88放进去。有人会问,1这个位置被占了,那下一个数据是1这个位置怎么办,这时候,我们还是同样的做法,给这个数据再计算一个哈希值。

插入88后的数组变为

 

冲突解决了,但我们读取数据的时候,好像又出现问题了,88的哈希值是0,发现数组0位置不是空的,那我们确定88在哈希表中?肯定不行,0这个位置存储的是77,不是88。我们的解决方法是判断0这个位置的值是不是88,不是的话,再计算88的哈希值是1,判断是1这个位置是否为空,为空,则88不在哈希表中;不为空,判断值是否为88,若是88,确定在哈希表中;如果值不是88,我们则继续计算哈希值是2,依次下去,直到找到88或者值为空的位置。

第二个问题,哈希表扩容

一个简单的解决办法是,当插入数据时,发现所有的位置都满了,我们就再分配一个大于原先空间的一片空间,把原来空间中的值重新哈希到新的空间中。

4. 哈希表的python实现

python中的字典就是哈希表,下面代码实现了一个简单的字典

class Dict:
    def __init__(self, size=10):
        self.size = size
        self.key = [None] * self.size
        self.data = [None] * self.size

    def __setitem__(self, key, value):
        assert isinstance(key, int)
        index = self.hash(key)
        if not self.key[index]:
            self.key[index] = key
            self.data[index] = value
        elif self.key[index] == key:
            self.data[index] = value
        else:
            start = index
            while self.key[index] and self.key[index] != key:
                index = self.re_hash(index)
                if index == start:
                    raise Exception('dict is full')

            if self.key[index]:
                self.data[index] = value
            else:
                self.key[index] = key
                self.data[index] = value

    def __getitem__(self, item):
        assert isinstance(item, int)
        index = self.hash(item)
        if not self.key[index]:
            raise KeyError(item)
        else:
            if self.key[index] == item:
                return self.data[index]
            else:
                start = index
                while self.key[index] and self.key[index] != item:
                    index = self.re_hash(index)
                    if start == index:
                        raise KeyError(item)

                if self.key[index] == item:
                    return self.data[index]
                else:
                    raise KeyError(item)

    def __contains__(self, item):
        assert isinstance(item, int)
        index = self.hash(item)
        if not self.key[index]:
            return False
        else:
            if self.key[index] == item:
                return True
            else:
                start = index
                while self.key[index] and self.key[index] != item:
                    index = self.re_hash(index)
                    if start == index:
                        break

                if self.key[index] == item:
                    return True
                else:
                    return False

    def hash(self, key):
        index = key % self.size
        return int(index)

    def re_hash(self, index):
        return index+1


a = Dict()
a[1]='3'
a[2]='4'
print(a[5])

 

三. 总结:

哈希表对于数据的插入,删除,更新操作复杂的平均是O(1),效率非常高,如果不关心数据的存储顺序,我们可以选取这种数据结构。

 

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

哈希表的原理及实现代码

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

哈希表的原理及实现代码

哈希表可以表述为,是一种可以根据关键字快速查询数据的数据结构一. 哈希表有哪些优点?不论哈希表中数据有多少,增加,删除,改写数据的复杂度平均都是O(1),效率非常高二. 实现哈希表1. 哈希表原理如果说每一个数据它都对应着一个固定的位置,那
2023-01-31

PHP 哈希表的原理、实现与常见问题

哈希表通过哈希函数将键映射到数组下标,实现快速查找、插入和删除。php 使用数组和 md5() 哈希函数实现哈希表,通过线性探查解决冲突。常见问题包括哈希冲突(可通过增加数组大小或优化哈希函数解决)、哈希碰撞(可通过安全散列函数避免)和性能
PHP 哈希表的原理、实现与常见问题
2024-05-07

java哈希表的原理是什么

Java哈希表的原理是利用哈希函数将键(key)映射到存储位置,通过对键进行哈希运算得到一个索引,然后将值(value)存储在该索引对应的存储位置中。具体原理如下:1. 哈希函数:哈希函数将键(key)转换为一个整数值,该整数值即为该键对应
2023-08-24

Java哈希表和有序表实例代码讲解

这篇文章主要介绍了Java哈希表和有序表,哈希表也称散列表,是一种以键值对形式存储记录的数据结构,该数据结构支持根据键的内容直接访问在内存特定位置的值,并且可以进行查找、添加和删除操作
2023-05-15

C++数据结构之哈希表的实现

哈希表,即散列表,可以快速地存储和查询记录。这篇文章主要为大家详细介绍了C++数据结构中哈希表的实现,感兴趣的小伙伴可以了解一下
2023-03-11

android长截屏原理及实现代码

小米系统自带的长截屏应该很多人都用过,效果不错。当长截屏时listview就会自动滚动,当按下停止截屏时,就会得到一张完整的截屏。该篇就介绍一下长截屏的原理上篇中介绍了android屏幕共享实现方式,该篇的原理和上一篇基本一致。获取view
2023-05-30

Java数据结构中实现哈希表的分离链接法

这篇文章主要介绍“Java数据结构中实现哈希表的分离链接法”,在日常操作中,相信很多人在Java数据结构中实现哈希表的分离链接法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java数据结构中实现哈希表的分离
2023-06-20

详解B+树的原理及实现Python代码

B+树是自平衡树的高级形式,其中所有值都存在于叶级中。B+树所有叶子都处于同一水平,每个节点的子节点数量≥2。B+树与B树的区别是各节点在B树上不是相互连接,而在B+树上是相互连接的。B+树多级索引结构图B+树搜索规则1、从根节点开始
详解B+树的原理及实现Python代码
2024-01-24

C++哈希表之闭散列方法的模拟实现详解

闭散列指(开放定址法)发生冲突时,如果哈希表没有被填满,则表内一定还有其他空闲位置,可以把冲突值放到下一个没有被占用的空余位置上。本文将模拟实现闭散列方法,需要的可以参考一下
2022-11-13

Android基站定位原理及实现代码

代码如下: import java.io.BufferedReader; import java.io.InputStreamReader; import org.apache.http.HttpResponse; import org.a
2022-06-06

MyBatisPlus代码生成器的原理及实现详解

这篇文章主要为大家详细介绍了MyBatisPlus中代码生成器的原理及实现,文中的示例代码讲解详细,对我们学习MyBatisPlus有一定帮助,需要的可以参考一下
2022-11-13

android IntentService实现原理及内部代码分享

很多网友可能发现Android中除了Service还有一个IntentService,他们之间到底有哪些区别呢? 在继承关系上而言IntentService是Service的子类,内部实现的代码中涉及到一些Android入门开发者不
2022-06-06

jQuery实现图片放大预览实现原理及代码

jQuery实现图片放大原理很简单,就是将图片显示的尺寸变大后放在浏览器的一个指定位置,从而实现图片的放大预览,下面有个不错的示例,感兴趣的朋友可以参考下
2022-11-15

Linux shell传递参数实现原理及代码实例

Shell 传递参数 我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推…… 以下实例我们向脚本传递两个参数,并分别输出,其中
2022-06-03

python实现希尔密码加密的示例代码

目录原理实现原理 希尔密码是运用基本矩阵论原理的替换密码,由Lester S. Hill在1929年发明。 每个字母当作26进制数字:A=0, B=1, C=2… 一串字母当成n维向量,跟一个n×n的矩阵相乘,再将得出的结果模26。(注意用
2022-06-02

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录