散列

散列又叫hash。是通过关键字把数据映射到指定位置的一种数据结构。理想的散列表,是一个包含关键字的固定大小的数组

哈希表存储的是键值对,其查找的时间复杂度与元素数量多少无关,哈希表在查找元素时是通过计算哈希码值来定位元素的位置从而直接访问元素的,因此,哈希表查找的时间复杂度为O(1)。

散列函数

hash(key) 通过一个散列的函数,将关键字进行计算,将计算的结果存到表里。如果关键字是一个整数,那么只要mod表长。如果关键字是一个字符串。通常的做法是将字符串转成ascii.然后再通过hash函数计算。 常见的哈希函数

  1. 直接寻址法

取关键字或者关键字的某个线性函数值作为哈希地址,即H(Key)=Key或者H(Key)=a*Key+b(a,b为整数),这种散列函数也叫做自身函数.如果H(Key)的哈希地址上已经有值了,那么就往下一个位置找,知道找到H(Key)的位置没有值了就把元素放进去.

  1. 数字分析法

分析一组数据,比如一组员工的出生年月,这时我们发现出生年月的前几位数字一般都相同,因此,出现冲突的概率就会很大,但是我们发现年月日的后几位表示月份和具体日期的数字差别很大,如果利用后面的几位数字来构造散列地址,则冲突的几率则会明显降低.因此数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址.

  1. 平方取中法

取关键字平方后的中间几位作为散列地址.一个数的平方值的中间几位和数的每一位都有关。因此,有平方取中法得到的哈希地址同关键字的每一位都有关,是的哈希地址具有较好的分散性。该方法适用于关键字中的每一位取值都不够分散或者较分散的位数小于哈希地址所需要的位数的情况。

  1. 折叠法

折叠法即将关键字分割成位数相同的几部分,最后一部分位数可以不同,然后取这几部分的叠加和(注意:叠加和时去除进位)作为散列地址.数位叠加可以有移位叠加和间界叠加两种方法.移位叠加是将分割后的每一部分的最低位对齐,然后相加;间界叠加是从一端向另一端沿分割界来回折叠,然后对齐相加.

  1. 随机数法

选择一个随机数,去关键字的随机值作为散列地址,通常用于关键字长度不同的场合.

  1. 除留余数法

取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址.即H(Key)=Key MOD p,p<=m.不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选得不好,则很容易产生冲突。一般p取值为表的长度tableSize。

一个简单的hash函数

int hash(char *key,int size){

    int temp = 0;

    while(*key != '\0') {

        temp += *key++;
} return temp%size; }

散列冲突

当使用hash函数计算的时候。可能会出现冲突。即通过hash函数计算得到的结果是一样的。举个例子


int hash(int key,int size) { return key%size;
} hash(20,10); hash(30,10); 会冲突

1.分离链接法

解决hash冲突的第一种方法就是分离链接法。简单的说就是拉链表。将冲突的元素放到该链表的后面。我们通过查找的时候,查到在对应的hashtable中。然后再遍历链表就能找到该元素。

3.开放定址法

分离链接的算法的缺点需要指针,给新单元分配地址空间需要时间。导致了算法的缓慢,另外一种解法也是通过链表的方法来实现的。叫开放定址法。在开放定址的方法中,如果有冲突发生,就尝试其他的单元。

  • 线性探测

如果h(k)被占用,就按照如下序列探测:(h(k)+p(1))%TSize,(h(k)+p(2))%TSize,...,(h(k)+p(i))%TSize,...

其中,h(k)为哈希函数,TSize为哈希表的长度,p(i)为探测函数。在(h(k)+p(i))%TSize的基础上,若发现冲突,则使用

增量p(i+1)进行新的探测,直到无冲突为止。

其中,根据探测函数p(i)的不同,开发地址发又分为:

线性探测法(p(i)=i:1,2,3,4,5,6,....);

二次(或平方)探测法:(p(i)=((-1)(i-1))(i)2:1,-1,4,-4,9,-9,......)

随机探测法(p(i):为随机数)

双散列函数(双散列函数h(key)、hp(key),如果h(key)出现冲突,则再使用hp(key)求取散列地址)

探测序列为:h(k),h(k)+hp(k), ... ,h(k)+i*hp(k),...

数据结构--hashtable(散列表)的更多相关文章

  1. Python与数据结构[4] -> 散列表[0] -> 散列表与散列函数的 Python 实现

    散列表 / Hash Table 散列表与散列函数 散列表是一种将关键字映射到特定数组位置的一种数据结构,而将关键字映射到0至TableSize-1过程的函数,即为散列函数. Hash Table: ...

  2. JS中数据结构之散列表

    散列是一种常用的数据存储技术,散列后的数据可以快速地插入或取用.散列使用的数据 结构叫做散列表.在散列表上插入.删除和取用数据都非常快. 下面的散列表是基于数组进行设计的,数组的长度是预先设定的,如有 ...

  3. 【PHP数据结构】散列表查找

    上篇文章的查找是不是有意犹未尽的感觉呢?因为我们是真真正正地接触到了时间复杂度的优化.从线性查找的 O(n) 直接优化到了折半查找的 O(logN) ,绝对是一个质的飞跃.但是,我们的折半查找最核心的 ...

  4. Python与数据结构[4] -> 散列表[2] -> 开放定址法与再散列的 Python 实现

     开放定址散列法和再散列 目录 开放定址法 再散列 代码实现 1 开放定址散列法 前面利用分离链接法解决了散列表插入冲突的问题,而除了分离链接法外,还可以使用开放定址法来解决散列表的冲突问题. 开放定 ...

  5. Python与数据结构[4] -> 散列表[1] -> 分离链接法的 Python 实现

    分离链接法 / Separate Chain Hashing 前面完成了一个基本散列表的实现,但是还存在一个问题,当散列表插入元素冲突时,散列表将返回异常,这一问题的解决方式之一为使用链表进行元素的存 ...

  6. jdk1.8HashMap底层数据结构:散列表+链表+红黑树,jdk1.8HashMap数据结构图解+源码说明

    一.前言 本文由jdk1.8源码整理而得,附自制jdk1.8底层数据结构图,并截取部分源码加以说明结构关系. 二.jdk1.8 HashMap底层数据结构图 三.源码 1.散列表(Hash table ...

  7. Nginx数据结构之散列表

    1. 散列表(即哈希表概念) 散列表是根据元素的关键码值而直接进行访问的数据结构.也就是说,它通过把关键码值映射到表中一个位置来访问记录, 以加快查找速度.这个映射函数 f 叫做散列方法,存放记录的数 ...

  8. hashtable——散列表

    2018-11-01 散列表---哈希表基于快速存取,时间换空间一种基于线性数组的线性表,不过元素之间并非紧密排列 散列函数--通过函数,有key关键码计算地址(相当于数组下标),函数尽可能使元素均匀 ...

  9. ruby hashtable散列表

    dict={'cat'=>'abc','dog'=>'def'}puts dict.size dict.keys返回所有的key, values返回所有的value. 删除: dict.d ...

  10. JavaScript 散列表(HashTable)

    TypeScript方式实现源码 // 特性: // 散列算法的作用是尽可能快地在数据结构中找到一个值. 在之前的章节中, 你已经知道如果 // 要在数据结构中获得一个值(使用get方法) ,需要遍历 ...

随机推荐

  1. JDK的下载,安装与环境的配置

    JDK的全称是JavaSE Development Kit,即java开发工具包,是sun公司提供的一套用于开发java应用程序的开发包,它提供了编译.运行java程序所需的各种工具和资源,包括jav ...

  2. apache 限制IP访问

    <Directory "/var/www"> Options All AllowOverride None Order Deny,Allow Deny From all ...

  3. Spring源码情操陶冶-PathMatchingResourcePatternResolver路径资源匹配溶解器

    本文简单的分析下spring对某个目录下的class资源是如何做到全部的加载 PathMatchingResourcePatternResolver#getResources PathMatching ...

  4. pycharm导入模块的时候遇到的两个错误

    1.from 包 import AES import后面一定是一个空格!!!!! 2.包的导入 上面多了一层报错 错误的原因是最外层多了一个pythonProject目录.改成下面的ok. 原因大佬这 ...

  5. 使用原生JS定位网页元素

    约定:1.<meta name="viewport" content="width=device-width">这种标记简称"wdw&qu ...

  6. Mysql大数据备份和增量备份及还原

    目前主流的有两个工具可以实现物理热备:ibbackup和xtrabackup ;ibbackup是需要授权价格昂贵,而xtrabackup功能比ibbackup强大而且是开源的 Xtrabackup提 ...

  7. Project support for both iOS 6 and iOS 7

    原文:https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/TransitionGuide/S ...

  8. PHP 变量的实现原理

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica } p.p2 { margin: 0.0px 0.0px 0.0px 0. ...

  9. Jenkins gitlab vue,angular,react 自动化构建【原】

    大致思路,(本篇主要讲vue ,当然了 angular react 也是一样配置) ,转发请注明原链接,谢谢 :) 1. 服务器上面配置jenkins (安装配置,不介绍) 2.新建item 自由风格 ...

  10. 利用while语句,条件为输入的字符不为'\n'.

    题目:输入一行字符,分别统计出其中英文字母.空格.数字和其它字符的个数. 1.程序分析:利用while语句,条件为输入的字符不为'\n'. 一个很简单的问题,其实换种方式就能完成,但是我就想怎么着才能 ...