今天第一次做Leetcode用到了散列表,之前学的数据结构的内容都忘了,正好趁热打铁补一补。

摘自其他博客的一个整合、

一、哈希表简介

数据结构的物理存储结构只有两种:顺序存储结构链式存储结构(像栈,队列,树,图等是从逻辑结构去抽象的,映射到内存中,也这两种物理组织形式),在数组中根据下标查找某个元素,一次定位就可以达到,哈希表利用了这种特性,哈希表的主干就是数组

比如我们要新增或查找某个元素,我们通过把当前元素的关键字 通过某个函数映射到数组中的某个位置,通过数组下标一次定位就可完成操作。

存储位置 = f(关键字)

另一种解释如下:

哈希表就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查找的值即key,即可查找到其对应的值。

哈希的思路很简单,如果所有的键都是整数,那么就可以使用一个简单的无序数组来实现:将键作为索引,值即为其对应的值,这样就可以快速访问任意键的值。这是对于简单的键的情况,我们将其扩展到可以处理更加复杂的类型的键。

使用哈希查找有两个步骤:

  1. 使用哈希函数将被查找的键转换为数组的索引。在理想的情况下,不同的键会被转换为不同的索引值,但是在有些情况下我们需要处理多个键被哈希到同一个索引值的情况。所以哈希查找的第二个步骤就是处理冲突
  2. 处理哈希碰撞冲突。有很多处理哈希碰撞冲突的方法,本文后面会介绍拉链法和线性探测法。

二、JAVA中 HashMap类的方法介绍

此处默认HashMap<Key Value>

1、clear()

clear() 的作用是清空HashMap。它是通过将所有的元素设为null来实现的。

public void clear() {
modCount++;
Entry[] tab = table;
for (int i = 0; i < tab.length; i++)
tab[i] = null;
size = 0;
}

2、containsKey()

containsKey() 的作用是判断HashMap是否包含key

public boolean containsKey(Object key) {
return getEntry(key) != null;
}

containsKey() 首先通过getEntry(key)获取key对应的Entry,然后判断该Entry是否为null

3、containsValue()

containsValue() 的作用是判断HashMap是否包含“值为value”的元素

public boolean containsValue(Object value) {
// 若“value为null”,则调用containsNullValue()查找
if (value == null)
return containsNullValue(); // 若“value不为null”,则查找HashMap中是否有值为value的节点。
Entry[] tab = table;
for (int i = 0; i < tab.length ; i++)
for (Entry e = tab[i] ; e != null ; e = e.next)
if (value.equals(e.value))
return true;
return false;
}

从中,我们可以看出containsNullValue()分为两步进行处理:第一,若“value为null”,则调用containsNullValue()。第二,若“value不为null”,则查找HashMap中是否有值为value的节点。

containsNullValue() 的作用判断HashMap中是否包含“值为null”的元素

4、entrySet()、values()、keySet()

它们3个的原理类似,这里以entrySet()为例来说明。
entrySet()的作用是返回“HashMap中所有Entry的集合”,它是一个集合。

// 返回“HashMap的Entry集合”
public Set<Map.Entry<K,V>> entrySet() {
return entrySet0();
} // 返回“HashMap的Entry集合”,它实际是返回一个EntrySet对象
private Set<Map.Entry<K,V>> entrySet0() {
Set<Map.Entry<K,V>> es = entrySet;
return es != null ? es : (entrySet = new EntrySet());
} // EntrySet对应的集合
// EntrySet继承于AbstractSet,说明该集合中没有重复的EntrySet。
private final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
public Iterator<Map.Entry<K,V>> iterator() {
return newEntryIterator();
}
public boolean contains(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<K,V> e = (Map.Entry<K,V>) o;
Entry<K,V> candidate = getEntry(e.getKey());
return candidate != null && candidate.equals(e);
}
public boolean remove(Object o) {
return removeMapping(o) != null;
}
public int size() {
return size;
}
public void clear() {
HashMap.this.clear();
}
}

5、get()

get() 的作用是获取key对应的value,它的实现代码如下:

public V get(Object key) {
if (key == null)
return getForNullKey();
// 获取key的hash值
int hash = hash(key.hashCode());
// 在“该hash值对应的链表”上查找“键值等于key”的元素
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}
return null;
}

6、put()

put() 的作用是对外提供接口,让HashMap对象可以通过put()将“key-value”添加到HashMap中

public V put(K key, V value) {
// 若“key为null”,则将该键值对添加到table[0]中。
if (key == null)
return putForNullKey(value);
// 若“key不为null”,则计算该key的哈希值,然后将其添加到该哈希值对应的链表中。
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
// 若“该key”对应的键值对已经存在,则用新的value取代旧的value。然后退出!
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
} // 若“该key”对应的键值对不存在,则将“key-value”添加到table中
modCount++;
addEntry(hash, key, value, i);
return null;
}

哈希表(Hash Map)的更多相关文章

  1. 算法与数据结构基础 - 哈希表(Hash Table)

    Hash Table基础 哈希表(Hash Table)是常用的数据结构,其运用哈希函数(hash function)实现映射,内部使用开放定址.拉链法等方式解决哈希冲突,使得读写时间复杂度平均为O( ...

  2. [CareerCup] 13.2 Compare Hash Table and STL Map 比较哈希表和Map

    13.2 Compare and contrast a hash table and an STL map. How is a hash table implemented? If the numbe ...

  3. Freemarker 中的哈希表(Map)和序列(List)

    freemarlker中的容器类型有: 哈希表:是实现了TemplateHashModel或者TemplateHashModelEx接口的java对象,经常使用的实现类是SimpleHash,该类实现 ...

  4. Redis原理再学习04:数据结构-哈希表hash表(dict字典)

    哈希函数简介 哈希函数(hash function),又叫散列函数,哈希算法.散列函数把数据"压缩"成摘要,有的也叫"指纹",它使数据量变小且数据格式大小也固定 ...

  5. 哈希表(Hash)的应用

    $hs=@() #定义数组 $hs=@{} #定义Hash表,使用哈希表的键可以直接访问对应的值,如 $hs["王五"] 或者 $hs.王五 的值为 75 $hs=@''@ #定义 ...

  6. PHP关联数组和哈希表(hash table) 未指定

    PHP有数据的一个非常重要的一类,就是关联数组.又称为哈希表(hash table),是一种很好用的数据结构. 在程序中.我们可能会遇到须要消重的问题,举一个最简单的模型: 有一份username列表 ...

  7. (四)Redis哈希表Hash操作

    Hash全部命令如下: hset key field value # 将哈希表key中的字段field的值设为value hget key field # 返回哈希表key中的字段field的值val ...

  8. 词典(二) 哈希表(Hash table)

    散列表(hashtable)是一种高效的词典结构,可以在期望的常数时间内实现对词典的所有接口的操作.散列完全摒弃了关键码有序的条件,所以可以突破CBA式算法的复杂度界限. 散列表 逻辑上,有一系列可以 ...

  9. 数据结构,哈希表hash设计实验

    数据结构实验,hash表 采用链地址法处理hash冲突 代码全部自己写,转载请留本文连接, 附上代码 #include<stdlib.h> #include<stdio.h> ...

  10. 什么叫哈希表(Hash Table)

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

随机推荐

  1. 五、Vi和Vim编辑器

    1. Vim编辑器: 在Linux下一般使用vi编辑器来编辑文件.vi既可以查看文件也可以编辑文件.三种模式: 命令行.插入.底行模式 切换到命令行模式:按Esc键: 切换到插入模式:按 i .o.a ...

  2. layui从子iframe打开父iframe的tab选项卡

    数据表格字段: {field: 'novelId', title: '小说ID',width:100,templet: '<div><a href="javascript: ...

  3. tfs增加用户

    1.windows上添加用户 2.tfs对应项目添加该用户 3.注意: 要设置服务器对应的本地安全策略   从网络上允许该用户访问

  4. angularjs i18n

    <!doctype html><html ng-app="myApp"><head>    <meta charset="utf ...

  5. [HAOI2008]移动玩具

    这又是一道神奇的搜索题...只要记录每种状态...然后暴力判断这种状态往后一步的情况... 广搜出最优解即可... 呆码: #include<iostream> #include<c ...

  6. 关于几天来研究使用css3动画的一点总结

    1. 为避免合成线程频繁计算导致性能降低, 使用transform属性,尽量避免使用width / height / padding / left 等. 2. 侧边栏下阴影遮罩层动画, 如果用back ...

  7. fiddler模拟弱网测试点

    弱网: oSession[“request-trickle-delay”] = “300”; 注释的也很明白,Delay sends by 300ms per KB uploaded.上传1KB需要3 ...

  8. linux centos7下源码 tar安装mysql5.7.23(5.7以上均可试用)

    1.工具:mysql-5.7.22-linux-glibc2.12-x86_64.tar.gz.centos7 2.解压后,将mysql-5.7.22-linux-glibc2.12-x86_64里面 ...

  9. random模块用法

    最近生病,学习进度少许拖延,, import random # 随机取0~1之间的小数 print(random.random()) # 随机取2数之间的整数 print(random.randint ...

  10. python学习笔记3-函数

    一.函数高级特性 1)列表生成式,列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式. eg: >>> list(r ...