1,什么是散列?

举个例子,在日常生活中,你将日常用品都放在固定的位置,当你下次需要该东西时,直接去该地方取它。这个过程就相当于散列查找。

若将它们随意杂乱无章地存放,当需要某件东西时,只能一个地方一个地方地逐一查找,这就相当于顺序查找。

在数据结构中,数组就相当于一张散列表,因为可以根据数组下标索引直接取得该位置上的元素。

2,什么情况下用到散列?

由于散列查找相对于其它查找而言,理论上只需要O(1)时间就可以找到某元素,因此,当查找是主要的任务时,散列就是实现词典的一种很好的选择。

3,散列函数的理解

散列查找中,需要提供一个查找键,根据该查找键来寻找值---(KEY,VALUE)....而在实际应用中,查找键描述的是现实世界中对象的性质,它不合适直接用来作为Value(值)的索引(索引一般是整数)。其次,查找键的范围可能很大,但是计算机的存储是空间使用得越少越合理。基于以上两个原因,需要使用散列函数将查找键转化为某个元素的索引。对于一个典型的散列函数,执行以下两个步骤:

①将查找键转换为一个称为散列码的整数-------解决索引问题

②将散列码压缩到散列表的索引范围------解决存储空间限制

4,在Java中,JDK类库String类的对象的hashCode是这样生成的:

对于字符串s而言,它的hashCode是基于每个字符unicode值乘以一个基于该字符在字符串中位置的因子g(其中 g=31)

如: s = u(0)u(1)……u(n-1)

散列码hash = u(0)*g^(n-1) + u(1)*g^(n-2)+……+u(n-2)*g+u(n-1),该多项式使用 Horner方法 可以写成一种等价的代数形式。该代数形式的多项式求值用程序表示如下:

        int hash = ;
int n = s.length();
for(int i = ; i < n; i++)
hash = g*hash + s.charAt(i);

5,JDK中对于64位long类型对象作为key的hashCode码按照如下方法生成:

int(key^(key>>32))

key一共有64位,首先将key右移32位(高32位补0),原来的key低32位的值被丢弃,再进行异或运算,就可以合并64位查找键的低32位的值和高32位的值(key中高32位的bit与低32位的bit异或),再运行强制类型转换,将结果转化成32位的值。这样就可以将一个64位的key结合它的每一位的值来获得一个32位的hashCode散列码。

6,散列表长度问题

散列表的长度不能为偶数,why?因为在将散列码压缩为散列表的索引时,通常是使用取模计算---c%n(c 为散列码,n 为散列表长度)

当 n 为偶数时,c%n 的奇偶性与 c 的奇偶性相同,若散列码偏向于奇数或者偶数(内存地址的散列码通常是偶数)这样得到的索引很难是均匀分布的。因此散列表的长度通常取奇数,最好取素数。

7,散列冲突的处理

这个知识点可以单独写一篇文章了。当在词典中插入元素时,若散列函数将查找键映射到一个已经使用的位置,则需要为该查找键相关联的值寻找另一个位置,有两种思路,一是使用散列表中的另一个位置。二是修改散列表的结构,使得散列表中的每个位置可以表示多个值。

这样列下散列冲突的处理类型分两种:

①开放定址法---对应第一种思路,总是为冲突的key在散列表中寻找下一个“未被使用”的位置。

②链地址法-----对应第二种思路,每个散列表中的位置可以指向一个链表,该链表称为桶。每个桶中则可以存放多个value。(将冲突的key对应的value插入到链表中)

开放定址法又分为三种情况:

❶线性探测开放定址----易产生一次聚集现象,即多个key问题被hash到同一个索引位置上。对于每个(key,value)只要表不满,总可以找到一个位置存放。

❷二次探测开放定址

❸再散列法---对冲突的key再进行一次hash。

散列之HashTable学习的更多相关文章

  1. 数据结构和算法 – 7.散列和 Hashtable 类

    7.1.散列函数 散列是一种常见的存储数据的技术,按照这种方式可以非常迅速地插入和取回数据.散列所采用的数据结构被称为是散列表.尽管散列表提供了快速地插入.删除.以及取回数据的操作,但是诸如查找最大值 ...

  2. PHP密码散列算法的学习

    不知道大家有没有看过 Laravel 的源码.在 Laravel 源码中,对于用户密码的加密,使用的是 password_hash() 这个函数.这个函数是属于 PHP 密码散列算法扩展中所包含的函数 ...

  3. 哈希表(散列)HashTable实现

    近期刷Leetcode发现凡是找字符串中反复字符或者数组中找反复数据的时候就不知道从何下手了. 所以决定学习一下哈希表解题.哈希表的原理主要是解决分类问题,hash表是介于链表和二叉树之间的一种中间结 ...

  4. 流畅的python第十章序列的修改,散列和切片学习记录

    只要实现了__len__和__getitem__两个方法即可将该类视为序列. 切片原理 动态存取属性 如果实现了__getattr__方法,也要定义__setattr__方法,以防对象行为不一致

  5. js 实现数据结构 -- 散列(HashTable)

    原文: 在Javascript 中学习数据结构与算法. 概念: HashTable 类, 也叫 HashMap 类,是 Dictionary 类的一种散列表实现方式. 散列算法的作用是尽可能快地在数据 ...

  6. 基于散列的集合 HashSet\HashMap\HashTable

    HashSet\HashMap\HashTable 1 基于散列的集合 2 元素会根据hashcode散列,因此,集合中元素的顺序不一定与插入的顺序一致. 3 根据equals方法与hashCode方 ...

  7. 散列表碰撞处理、开链法、HashTable散列

    散列表碰撞处理.开链法.HashTable散列 /** * 散列表碰撞处理.开链法.HashTable散列. * 将数组里的元素位置,也设置为数组,当两个数据的散列在同一个位置时, * 就可以放在这个 ...

  8. Shiro入门学习之散列算法与凭证配置(六)

    一.散列算法概述 散列算法一般用于生成数据的摘要信息,是一种不可逆的算法,一般适合存储密码之类的数据,常见的散列算法如MD5.SHA等,一般进行散列时最好提供一个salt(“盐”),什么意思?举个栗子 ...

  9. 【数据结构与算法Python版学习笔记】查找与排序——散列、散列函数、区块链

    散列 Hasing 前言 如果数据项之间是按照大小排好序的话,就可以利用二分查找来降低算法复杂度. 现在我们进一步来构造一个新的数据结构, 能使得查找算法的复杂度降到O(1), 这种概念称为" ...

随机推荐

  1. .NET Framework 版本和依赖关系[微软官方文档]

    .NET Framework 版本和依赖关系 微软官方文档: https://docs.microsoft.com/zh-cn/dotnet/framework/migration-guide/ver ...

  2. Qt__事件处理机制

    一.Qt事件 Qt会将系统消息(如鼠标按键.键盘按键等)转化为Qt事件,Qt事件被封装为对象且定义该对象的类均继承自抽象类QEvent. 二.Qt事件的产生 1.操作系统产生 Spontaneous ...

  3. hive分区表

    分区表创建 row format delimited fields terminated by ',';指明以逗号作为分隔符 依靠插入表创建分区表  从表sample_table选择 满足分区条件的 ...

  4. 周刷题第二期总结(Longest Substring Without Repeating Characters and Median of Two Sorted Arrays)

    这周前面刷题倒是蛮开心,后面出了很多别的事情和问题就去忙其他的,结果又只完成了最低目标. Lonest Substring Without Repeating Characters: Given a ...

  5. 最实用的深度学习教程 Practical Deep Learning For Coders (Kaggle 冠军 Jeremy Howard 亲授)

    Jeremy Howard 在业界可谓大名鼎鼎.他是大数据竞赛平台 Kaggle 的前主席和首席科学家.他本人还是 Kaggle 的冠军选手.他是美国奇点大学(Singularity Universi ...

  6. Linux系统——程序员跳槽必备

    相信在看这篇文章的你,曾经或者现在是否跳槽呢,在北上广一线城市,你是否还在挣着那可怜巴巴的工资,过着拮据生活呢?但是自己想跳槽,却没有一技之长或者是自己的技术找工作太难了,那么我建议你学习下linux ...

  7. HS BDC HDU - 3472(混合欧拉路径)

    题意: 就是混合欧拉路径板题 解析: 欧拉路径加一条t_ ---> s_  的边就变成了欧拉回路,所以利用这一点,如果存在两个奇点,那么这两个奇点出度大的是s_,入度大的是t_,加一条t_ -- ...

  8. 自学Python6.2-类、模块、包

    自学Python之路-Python基础+模块+面向对象自学Python之路-Python网络编程自学Python之路-Python并发编程+数据库+前端自学Python之路-django 自学Pyth ...

  9. 【Code Chef】April Challenge 2019

    Subtree Removal 很显然不可能选择砍掉一对有祖先关系的子树.令$f_i$表示$i$子树的答案,如果$i$不被砍,那就是$a_i + \sum\limits_j f_j$:如果$i$被砍, ...

  10. Python--Django学习笔记2

    本篇介绍Django中的Model层. 首先介绍sqlite3,这是在当前版本中Django默认使用的数据库,sqlite也是Android中所使用的数据库. 接着介绍最最最常见的MySQL数据库如何 ...