Hash算法和Hash表简述

Hash算法

hash,即散列,是指把任意长度的输入,通过hash算法,变成固定长度的输出,输出的就是散列值

散列过程是一个压缩过程,得到的散列值占用的空间小于原来的输入。

不同的输入可能会导致相同的散列值,这就是哈希冲突,或者说发生了"碰撞"。

一个好的hash算法,就是要减小发生碰撞的几率。

常见的Hash算法:

  1. MD4:适用于32位处理器,已弃用。
  2. MD5:Message-Digest Algorithm,产生出一个128位(16字节)的散列值(hash value)。
  3. SHA-1:Secure Hash Algorithm 1,美国国家安全局设计,可以生成一个160位(20字节)散列值

JDK8中HashMap的Hash算法:

static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
//Object中的hashCode()是一个native方法,用C或C++写的

hash算法的应用:就我所学,就是数字摘要啊,数字摘要就是通过hash算法后得到的哈希值(hash value),可以标识这份数据。并且hash过程是不可逆的,无法通过数字摘要还原这份数据。

Hash表

Hash表是基于Hash算法的一种数据结构,数组的特点是查询快,增删慢,链表的特点是查询慢,增删快,hash table就是二者结合的产物。

Hash表具有快速存取的特点,援举一个在skywang12345中看到的例子:

假设,HashSet中已经有1000个元素。当插入第1001个元素时,需要怎么处理?因为HashSet是Set集合,不允许有重复元素。
将第1001个元素逐个的和前面1000个元素进行比较”?显然,这个效率是相等低下的。散列表很好的解决了这个问题,它根据元素的散列码计算出元素在散列表中的位置,然后将元素插入该位置即可,这样就达到快速存取的目的,并且只要散列码不重复,就能保证元素没有重复。

Hash表是如何进行数据存取的?

哈希表本质上是一个数组,用来储存关键码值(即键值对,key-value pair),在进行存取时,通过特殊的索引值来访问数组中的元素,特殊的索引值是指通过哈希函数将键(key)进行转换后得到的值

看一个链式Hash表

Hash算法和Hash表简述_第1张图片(图片地址:https://images2017.cnblogs.com/blog/1281268/201712/1281268-20171206081611534-142637156.png)

所谓的链式Hash表,是一个存放了多个链表数组,链表用来存放数据,每个链表称作是一个桶(bucket)。

再看HashMap的源码:

Hash算法和Hash表简述_第2张图片

可见HashMap中有一个内部类Node实现了Map.Entry,Node中持有下一个节点next的引用,这样就构成了一个链表。所以HashMap本质上就是一个链式哈希表。

以上,就我现在对Hash表的理解来看,这种数据结构就是为了在保证元素不重复的前提下,实现对元素的快速存取

 

 

你可能感兴趣的:(算法)