数组这个结构,相信大家在平时的开发中经常用到,那我们今天就来聊聊这个基础的数据结构。
1.如何实现随机访问
数组是一种线性表结构,用一组连续的内存空间存储一组具有相同类型的数据。
这里有几个概念要注意一下:
- 线性表:数据排列像一条线一样的结构,表上的数据最多只有前后两个方向,链表、队列、栈也是线性表结构。
- 连续的内存空间和相同类型的数据
- 随机访问
寻址公式:a[i]_address = base_address + i*type_size
2.低效的“插入”和“删除”
- 为了保证数据连续,在数据插入时,需要对数据进行移动,为了避免数据移动,可以直接将第k位的数据搬移到数据元素的最后,把新的元素直接放入第k个位置。
- 删除操作
- 类似插入,删除元素时,需要对之后的数据进行搬移
- 可以将多次删除操作集中在一起执行,为了避免进行多次数据搬移,我们可以先记录已经删除的数据。当数组没有更多存储空间时,我们再触发一次真正的删除操作。
- 这即是JVM标记清除垃圾回收算法的核心思想
3.警惕数组越界
4.容器能否完全替代数组
- 容器类:java中的Array List、C++STL中的vector
- ArrayList的优势是:
可以将很多数组操作的细节封装起来
支持动态扩容
若事先知道数据大小,最好在创建ArrayList的时候事先指定数组大小。因为,扩容操作涉及内存申请和数据搬移,比较耗时
3.何时用数组
ArrayList无法存储基本类型,而且装拆箱有性能消耗,若关注性能,则选用数组
若数据大小已知,并对数据的操作很简单,用不到ArryList提供的大部分方法,也可直接使用数组。
表示多维数组时,用数组往往会更加直观,如object[][],而用ArrayList则定义为ArrayList<ArrayList> array;
4.总结
业务开发使用容器足够了,省时省力。
底层开发,性能要求高,则数组优于容器。
二维数组的寻址公式:
对于m*n的数组,a[i][j](i<m,j<n)的地址为:
address=base_address+(i*n+j)*type_size