【数据结构】-数组的特性

数组

  • 定义

数组(Array):是一种线性表数据结构,它用一组连续的内存空间,来存储一组具有相同类型的数据。

关键定义点:
1.线性表
线性表,从字面上理解就是数据排成一条线一样的结构,每条线上的数据最多只有向前和向后两个方向。
数组、链表、队列、栈都是线性表结构。
如图所示
在这里插入图片描述
非线性表结构:二叉树、堆、图等,非线性表中,数据之间不是简单对前后关系(交叉、父子等)。

2.连续内存空间&&相同类型数据
计算机会为数组开辟一个连续的内存空间,这个连续性保证了如果随机访问数据中的元素,它的时间复杂度为O(1),也就是查找的数据很快,但是有利有弊。
如果delete、add数组中的元素,为了保持其连续性,那么就需要进行大量的数据搬移,这样就导致它的效率很低。

  • 数组的访问

假设定义这样一个数组int[] a = new int[10],计算机会为这个数组分配一个连续的内存空间(内存地址为1000 ~ 1039),内存块的首地址为1000
说明,int类型存储范围为4个字节,所以10个元素内存空间 4 * 10 = 40

内存地址对应如下

元素 内存块地址
a[0] 1000 - 1003
a[1] 1004 - 1007
a[2] 1008 - 1011
a[3] 1012 - 1015
a[4] 1016 - 1019
a[5] 1018 - 1023
a[6] 1022 - 1027
a[7] 1026 - 1031
a[8] 1028 - 1035
a[9] 1032 - 1039

寻址公式

a[i]_address = base_address + i * data_type_size

data_type_size:表示每个元素的大小
base_address:内存的首地址

如果访问a[4]元素,根据寻址公式a[4]_address = 1000 + 4 * 4 = 1016,就能立刻定位到对应的内存地址

时间复杂度分析
从上面访问分析,数组根据下标随机访问的时间复杂度为O(1),可以看出,数组很适合查找操作。
那么数据访问的时间复杂度一定是O(1)吗?
答案是否定的。
如果采用二分查找法,时间复杂度是O(logn),后面会分析

  • 数组的插入和删除(低效)

1.数组的插入

假设数组的长度为n,假设现在需要将一个数据插入到第k的位置,该怎么操作呢?
想一下,数组a[n]是一个连续的内存空间,如果插入新的元素到a[k],那么需要将a[k]的位置腾出来,就需要把a[k]~a[n]的元素整体后移一位。
这里就涉及到数据的搬移操作了。

  • 时间复杂度分析
  • 最坏的情况:k = 0,也就是说将数据插入到数组的第一位,那么需要将后面n个数据整体后移一位,那么时间复杂度是O(n)
  • 最好的情况:k = n,也就是说直接把元素插入到数组的最后一位,这样数据不用搬移,那么时间复杂度为O(1)

在每个位置插入元素的概率是一样的,所以平均时间复杂度就是O(n)

  • 场景2:插入数据的时间复杂度为O(1)的场景
    在一个无序的数组中,数组存储的数据没有任何规律,只是一个存储数据的集合,这时候如果将某个数据插入到a[k]的位置,未了避免数据的迁移,
    可以直接将a[k]的数据搬移到数组的最后,然后把新的数据放到a[k],这样时间复杂度就降为O(1)了。

例如:数组元素:a,b,c,d,e
现在要把k插入到第三个位置,利用上面简单的方法,就变成了:a,b,k,d,e,c

2.数组的删除
删除数组中的元素,为了保持内存的连续性,也需要搬移数据操作。

  • 时间复杂度分析
    • 最好的情况:删除数组最后一位的元素,无需搬移数据,时间复杂度为O(1)
    • 最坏的情况:删除数组第一位元素,时间复杂度为O(n)

试想一下,每删除一个元素,都会触发数据的搬移操作,假如要依次删除多个元素,那么每次搬移数据操作非常低效。
那么有没有更好的办法解决呢?

实际上在一些特殊场景,在不追求数组中数据的连续性的条件下,可以将多次删除操作集中在一起执行,删除效率会提高很多。

例如:数组中依次存放:a,b,c,d,e,f,g,h,现在要依次删除a,b,c三个元素
解决思路就是:
先记录下已经删除的数据,每次的删除操作只是记录数据已经被删除(状态控制?),当数组中没有更多的存储空间时,再触发执行真正的删除操作,这样就大大减少了每次删除操作导致的数据搬移。

知识点扩展

该思想据说是JVM标记清除垃圾回收算法的核心思想,下去研究一下,学一下

学习后心得,了解了数据结构的具体特性后,在回过头去看基于数组实现的这些类的源码,会更清晰。

发布了7 篇原创文章 · 获赞 3 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览