数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据。
线性表(Linear List)
顾名思义,线性表就是数据排成像一条线一样的结构。
非线性表
比如二叉树、堆、图等。之所以叫非线性,是因为,在非线性表中,数据之间并不是简单的前后关系。
连续的内存空间和相同类型的数据
计算机会根据数据类型给每个数据分配相同内存单元。计算机通过寻址公式访问数组中元素【这就是为什么数组以0为初始下标的原因】
寻址公式:
a[i]_address = base_address + i * data_type_size
对于 m * n 的数组,a [ i ][ j ] (i < m,j < n)的地址为:
address = base_address + ( i * n + j) * type_size
注意:
- 数组支持随机访问,根据下标访问元素的时间复杂度为O(1)。
- 未排序查找元素时间复杂度为O(n);排序后用二分法查找元素时间复杂度为O(logn)。
插入与删除
数组的插入与删除涉及到元素的搬移,所以时间复杂度均为O(n)。
优化插入
对于数组中存储的数据并没有任何规律,数组只是被当作一个存储数据的集合:
优化删除
删除a,b,c就要搬移三次后续数据。我们可以先记录下已经删除的数据。每次的删除操作并不是真正地搬移数据,只是记录数据已经被删除。当数组没有更多空间存储数据时,我们再触发执行一次真正的删除操作,这样删除a,b,c只需要搬移一次!【JVM标记清除垃圾回收算法的核心思想】
总结:
对于业务开发,直接使用容器就足够了,省时省力。毕竟损耗一丢丢性能,完全不会影响到系统整体的性能。但如果你是做一些非常底层的开发,比如开发网络框架,性能的优化需要做到极致,这个时候数组就会优于容器,成为首选。