数组,我们经常使用,单我们对它真的了解吗?我想,一些人对数据应该是知其然,但是不知其所以然,这里,我就总结。
要理解数组,首先要知道它是什么数据结构。数组,是一种线性表,它在底层,使用的一组连续的内存空间,不可以,必须连续,这是它的一大特点。
不仅数组是线性表,栈,队列,链表,都是线性表结构。
线性表理解数组,我们抓住两个重要特性,1:线性表,2:连续存储。
正是连续存储,造就了数组能够随机访问的特点,同时,也给数据带来了一个最大的问题,不能够以线性时间进行插入删除。
为什么会这样,首先看看为什么能够随机访问。
长度为10 的int类型数组可以看到,数组初始化是一个在计算机中的连续内存空间,内存块的首地址为 base_address = 1000。
计算机会为每一个内存单元分配一个地址,当我们需要访问这个内存单元的时候,计算机会通过计算它的地址来访问它,a[i]_address = base_address + i * data_type_size。
就上面那个公式,假如一个单元是4个字节,那么想要访问一个内存单元,就可以很方便的计算得到,然后直接访问,这就是它能随机访问的根本原因。
但是当我们想要插入数据时,如果要插入的位置在数组末尾,就很方便,不需要多余操作,但是如果要出插入的位置在数组中间,那么就需要把待插入位置后面的元素都向后移一位。
当我们进行删除操作的时候,为例保证内存的连续性,也需要把所有的数据都向前移动一位,所有就十分耗时。
在java中,ArrayList的底层就是使用数组进行封装的,作为一个容器类,它相较于数组肯定是有很多优点的,当数组容量不够时,它能够自动进行扩容,将数组大小扩大为原来的1.5倍,不过由于扩容是一个十分耗时的操作,它需要将原来的数组数据拷贝到一个新的数组内,所以如果我们事先能够确定数组大小,那么就最好在创建ArrayList对象时就指定大小,这样就不需要进行扩容操作了,(初始化时是10大小)。
理解了数组的一些操作原理,我们就可以对数组进行一些练习以进行加固理解,下面是四道数组的题目。
https://leetcode-cn.com/problems/container-with-most-water/
https://leetcode-cn.com/problems/move-zeroes/
网友评论