哈希表(hash table)
也叫散列表,是一种非常重要的数据结构
一、其他一些数据结构的一些性能
数据结构的物理存储结构只有两种:顺序存储结构和链式存储结构。
顺序存储结构:内存地址连续,比如数组等
链式存储结构:内存地址不连续,比如二叉树,图等
数组
数组分为有序数组和无序数组,采用一段连续的存储单元来存储数据。
当我们知道他的下标表达方式对它进行查找时,时间复杂度为O(1);
当我们不知道下表表达式时,查找则需要遍历整个数组,时间复杂度为O(n);若对于有序数组来说,我们可以采用二分法对其进行查找,时间复杂度为O(logn);
对于一般的插入删除操作,由于数组是连续的,故会涉及到数组元素的移动,其平均复杂度为O(n)。
链表
链表的查找操作需要遍历链表逐一进行比对,复杂度为O(n)
二叉树
对一棵相对平衡的有序二叉树,对其进行插入,查找,删除等操作,平均复杂度均为O(logn)。
最坏情况:只有左子树或者只有右子树的二叉树,时间复杂度为O(n);
最好情况:平衡二叉树,时间复杂度为O(logn)。
二、构造平衡二叉树
平衡因子:左子树的深度-右子树的深度 的绝对值小于等于1
如果大于1,则进行旋转
LL型旋转:根结点向左拉取
RR型旋转:根结点向右拉取
LR型旋转:造成不平衡节点变为根节点,原先的根结点变为右子树,不平衡节点的父结点变为左子树
RL型旋转:造成不平衡节点变为根节点,原先的根结点变为左子树,不平衡节点的父结点变为右子树
由于平衡二叉树旋转起来太浪费时间,于是衍生出了红黑树。
三、HashMap
Hash表:
它的主干就是一个Entry数组。Entry是HashMap的基本组成单元,每一个Entry包含一个key-value。
Hash表是在java中的一个表现,java开发者帮我们写好的。
HashMap是由数组加链表所组成的一个静态类,主体是数组,数组长度默认为16,链表是为了解决哈希冲突而存在的
Hash算法:
hash(+关键字)得到一个int类型的数据,用这个数据除以一个固定的值,结果的范围是在hash表的地址当中(默认0~15)(关键词也就是key值)
查询:get(关键字),和hash算法同样的方式得到地址。
如果定位到的数组位置不含链表(即不产生哈希冲突,当前entry的next指向null),那么仅需一次寻址即可,时间复杂度为O(1);
如果定位到的数组包含链表(即已经产生了哈希冲突),那么查找时需要遍历链表,时间复杂度为O(n);
Hash冲突(也叫Hash碰撞):
两个不同的元素,通过哈希函数得出的实际存储地址相同
解决方法:
1、开放定址法:发生冲突,继续寻找下一块(向左或者向右)未被占用的存储地址
2、拉链法(最常用也最好用):往下拉一个链表
HashMap采用的就是拉链法,使用数组加链表
扩容:
两个方式1、数组扩容2、链表变红黑树
1、扩容:存在一个扩容因子:0.75,当达到0.75倍就会扩容
2、JDK1.8,当链表的长度,大于等于8的时候,他就会变成一个红黑树
hashcode()方法:
将这个值的地址转换成一个int类型的值
pulval操作: