已知一个按照升序排列的有序数组:arr={3,5,7,10,11,12,18}
可以用“树”来表示。
注意:每棵树只有一个根节点,根节点下可以有任意的子节点,子节点又可以有任意个子节点,当子节点下无子节点,该子节点被称为叶,每个节点只有一个父节点。
思路:
1:为了保持左右平衡,有序数组中间的数就是树的根节点。
2:height≈log2(N)=二分查找的时间复杂度,树的高度越低,时间复杂度会越好。
10
5 12
3 7 11 18
arr={10,11,22,13,4,5,16,17,48,69}
list查找方式的时间复杂度为:
list.get(0)==17?-->list.get(1)==17?...即为O(N)。
Map查找的时间复杂度为:
17%10=7-->arr[7],即为O(1)。
碰撞:如果通过计算后的两个或多个key的hash得到的index相同,则被称为碰撞,在这个位置会储存多个键值对,它们通过next属性链接在一起,但数组中存储的是最后插入的元素。
如果碰撞发生太多,map的size会越来越大,退化成链表。
map和双重for的性能对比:
举例代码:
双重for循环:
map实现:
map实现:
测试结果:
双重for循环,遍历list1中每个数据与list2对比,时间复杂度是O(2),将其中一个list转化为map之后,成为了并列for循环,遍历list后通过list.get(i)的key直接查询对应的value此时的时间复杂度为O(1)。这里要注意数据小的使用list,数据大的使用Map提高性能。
map的缺陷:
HashMap底层是通过数组和链表的数据结构实现的,如果每次计算的hash值是同一个,会造成链表长度过长,如果每次计算的hash值都不一样,会导致HashMap的容量不断扩大,为了解决这些问题,使用红黑树维持树的平衡。