数组时最基础的数据结构之一,几乎所有的语言都支持数组;
基本特点
那么数组具有哪些特点呢?
1、每个元素的内存大小固定,数组可容纳的元素个数固定
2、数组占用的空间是连续的
正是由于内存空间连续的特点,所以可以很好的利用缓存。
3、数组中的元素是有顺序的,并且是线性的
4、通过元素的位置访问数组元素,时间复杂度为1;
数组是如何做到按照位置访问,时间复杂度为1的呢?
基于内存连续以及每个元素的内存占用相同并且是固定的,那么在记录数组首地址的情况下,第一个元素的内存地址即为首地址,第n个元素的地址为(n-1) * cost_one 其中cost_one是每个元素占用内存大小,也就是想通过元素位置计算元素地址,然后直接访问。
常规的操作与处理
- 按照位置访问元素
具体如何访问在上一段中已经介绍了
- 插入和删除元素
这里需要分情况讨论,
- 最后一个位置插入和删除元素,时间复杂度和空间复杂度为1
- 在非最后一个位置插入和删除元素,同时需要保证其他元素的相对顺序,时间复杂度为O(n),因为其他元素需要进行移动。
- 在非最后一个位置插入和删除元素,但不需要保证其他元素的相对顺序,时间复杂度可以做到O(1);
比如在某个位置插入元素,先将此位置的元素插入的数组尾部,然后将待插入的元素放到此位置即可;删除元素时,将最后一个元素的位置放到删除的位置即可。
另外,对于删除元素还有一种做法,先将元素删除并标记删除,其他位置并不移动,然后在合适的时机再进行统一的元素移动。很类似于JVM的标记-清除算法
数组排序
常见的选择排序、冒泡排序、插入排序时间复杂度O(n^2),空间复杂度为O(1);
快速排序、归并排序、堆排序时间复杂度均为O(nlogn),空间复杂度快排为O(1),后两者为O(n);
数组排序是数组操作的基础,很多数组相关的算法处理的前提都是排序处理,比如二分查找算法
再比如寻找数组的众数,传统基于Map的统计空间复杂度O(n),如果事先采用空间复杂度O(1)的排序算法进行排序,那么中间位置的元素一定为众数,空间复杂度可以由O(n)降到O(1);
当涉及到数组问题时,不妨假设数组是有序的,获取会有更好的处理方式。
这些知识理解了吗?下一篇连载将会介绍一些针对数组的练习题
技术连载:开篇词
技术连载:连载提纲设计思路