散列表(Hash Table)又名哈希表/Hash表,是根据键key直接访问在内存存储位置的值value的数据结构,它是由数组演化而来的,利用了数组支持按照下标进行随机访问数据的特性。但这个键key有时不是纯数值,不能够做为数组的下标,这时就可以把这个非纯数值的key转为数值作为数组的下标,转换可以使用散列函数进行转换。
散列函数:将键key映射为数组下标的函数叫做散列函数。可以表示为:hashValue=hash(key)
散列函数需要满足一些基本要求:
1.散列函数计算得到的散列值必须是大于等于0的正整数,因为hashValue需要作为数组的下标。
2.如果key1==key2,那么经过hash后得到的哈希值也必须相同,即hash(key1)==hash(key2)
3.如果key1!=key2,那么经过hash后得到的哈希值也必不相同,hash(key1)!=hash(key2)
但是实际情况下找一个散列函数做到不同的key计算得到的散列值都是彼此不同的这是几乎不可能的,如MD5算法、SHA算法等都无发做到,这就是散列冲突(也可以叫哈希冲突、哈希碰撞,本质就是指多个key映射到同一个数组下标位置)
散列冲突的解决办法-链表法:在散列表中,数组的每个下标位置我们可以称之为桶(bucket)或者槽(slot),每个槽都会对应一条链表,所有散列值相同的元素都放到相同槽位对应的链表中,有多个key最终的hash值是一样的,就会存入数组的同一个下标中,下标中挂一个链表存入多个数据.
插入操作,通过散列函数计算出对应的散列槽位,将其插入到对应链表中即可,插入的时间复杂度是O(1)。
当查找、删除一个元素时,我们同样通过散列函数计算出对应的槽,然后遍历链表查找或者删除,平均情况下基于链表法解决冲突时查询的时间复杂度是O(1),散列表可能会退化为链表,查询的时间复杂度就从O(1)退化为O(n),将链表法中的链表改造为其他高效动态的数据结构如红黑树,查询的时间复杂度是O(logn)。
将链表法中的链表改造成红黑树,可以防止DDos攻击
DDos攻击:分布式拒绝服务攻击(Distributed Denial of Service )
指处于不同位置的多个攻击者同时向一个或数个目标发动攻击,或者一个攻击者控制了位于不同位置的多台机器并利用这些机器对受害者同时实施攻击(像僵尸爆发一样)。由于攻击的发出点是分布在不同地方的,这类攻击称为分布式拒绝服务攻击,其中的攻击者可以由多个。