前言
本文主要介绍动态数组基本概念以及ArrayList
扩容时间复杂度分析。
动态数组
说起动态数组,我们首先来看下什么是静态数组?
静态数组就是初始化后,数组长度不会再变的数组。与之相反,动态数据的长度是可以变化的,当数组中存储数据时存不下时,他会自动进行扩容以能够存放更多的数据。
比如,现在有一个数组长度为4,当放入4个元素时,数组容量已经满了,当要放入第5个元素时,动态数组会先生成一个新的数组,长度为原来的2倍,然后把原数组的数据进行复制过去,再进行放入第5个元素,如果在接下来放入的过程中,容量又不够了,那么动态数组就会再把长度扩大一倍,以此类推。
看到这里,是不是想起了Java
中的ArrayList
?ArrayList
底层也是数组,也会自动扩容,只不过ArrayList
扩容时,会扩大到原来的1.5
倍。
扩容时间复杂度
那么就产生了一个问题,我们知道在数组中查询一个元素的位置的时间复杂度为O(1),那么在ArrayList
中查找一个元素时,如果已经扩容完了,那么查询一个元素的位置的时间复杂度也为O(1)。
但是,我们来看下ArrayList
在扩容时的大致过程:
- 原数组中容量满了。
- 生成一个新的数组,长度为原来的1.5倍。
- 把原数组中的元素复制到新的数组中。
- 原数组销毁。
那么,这个ArrayList
的扩容操作会不会影响ArrayList
的整体表现呢?
扩容时间复杂度分析
先来分析下,在数组中加入N个元素时,扩容的总代价是多少?
为了方便分析,这里假设ArrayList
扩容时,会扩大到原来的2
倍计算,不会影响整体的时间复杂度。