时间复杂度
时间复杂度 是程序做了多少常数时间操作的指标。
估算时间复杂度,要用最差情况去估计时间复杂度。
动态数组
- 什么是 动态数组?—> ArrayList
- 动态数组的扩容和使用。
查询 —> 寻址 O(1)
扩容行为会影响ArrayList行为吗?扩容行为从时间复杂度的角度来说,对ArrayList整体性能,没有影响。
ArrayList动态数组扩容时间复杂度为 O(1);
ArrayList比固定数组,多常数级别的操作,但是在时间复杂度上,没有影响。也就是说,由于扩容行为所以会比固定数组慢一点,但这种慢,只是常数时间的慢。
所以说动态数组虽然有扩容,但是整体性能在时间复杂度的影像上,没有。做到与固定数组一样的好,还能扩容。
只是常数时间的差,但是不影响时间复杂度。
所以,可以放心使用JAVA中的ArrayList,因为从时间复杂度上来说,他就跟固定数组一样。工程大量使用ArrayList.
哈希表 HashMap
哈希表增删改查时间复杂度全部为 O(1);但是要注意,这个常数时间,是一个比较大的常数时间。
在不重写内部方法的情况下,裸着用,有两种传递方式(使用map.containsKey()检验):
- 内部按值传递的数据
哈希表内部,不管地址,只要你查的是一个东西,我就告诉你。
原生类型,按值传递。地址不同没关系,只要属性相同。 - 内部按引用传递的数据
非基础类型,非原生类型,内部按引用传递。必须是相同对象or相同对象地址。
不同传递方式,使得一条记录<K, V>在哈希表中 所占空间是不同的。按值传递,是值所占用的全部字节。而引用传递,(比如两个Node),一条记录只占两个地址所占的字节数 8+8=16B。
PS: Java地址 8 字节?
map.put 既是 新增 操作,也是更新 V 的操作
有序表 TreeMap
内部会按照key排好序。提供功能诸如,firstKey(),lastKey(),floorKey(),ceilingKey()
但是,与哈希表最大的区别,基本所有的方法,时间复杂度为 O(logn) 级别 .
非原生引用,不能直接用。要重写方法。因为TreeMap要求key一定是要比较的。可以使用外部比较器。