数据结构篇 --- 线性表数据结构,数组

数组

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

数组特性

线性表

线性表(Linear List)数据是线性排列的,每个线性表中的数据最多只有一个头和一个尾(或者一个前一个后),线性表数据结构包括:数组、队列、栈、链表等

非线性表中,数据之间并不是前后关系,一个数据可能跟多个数据有关系,非线性表包括 二叉树、堆、图等。

连续的内存空间

如图所示,系统给数组分配了一个连续的内存空间,即数组各个内元素的存地址也是连续的

当我们需要访问到数组的某个位置的元素时,可以根据首地址与数组中元素类型所占的内存大小以及数组角标,计算出目标元素的地址:

数组某个元素的内存地址 = 数组首地址+数组角标*数组元素类型的大小

有了地址了,就可以获取到元素值具体是多少。
为什么数组的下标一般是从0开始,可以从这个公式看出一点端倪
如果下边从1开始,那么
数组某个元素的内存地址 = 数组首地址+(数组角标-1)*数组元素类型的大小
每次随机访问某一个元素的时候都要执行减1操作,这对CPU来说,就是多执行了一次减法指令;
还有一个原因,可以从Java语言的起源来说,C语言的数组的下标是从0开始的,后来或许为了降低开发者的学习成本,Java数组效仿了C语言数组,下标也是从0开始。

支持随机访问

在这里插入图片描述

​ 根据上述描述,我们可以知道数组可以支持随机访问,且根据下标随机访问的时间复杂度是O(1)

数组的插入和删除数据效率低

因为数组是连续的内存空间,如果插入数据到数组的开头位置的元素,或者删除开头位置的元素,都要把数组中其它数据向后或者向前挪,从而保证内存的连续性。
如果插入数据的位置是数组末尾或者删除的数据是数组末尾,则不需要移动数据。
根据以上分析,最好时间复杂度是O(1)最坏时间复杂度是O(n),平均时间复杂度是1* 1/n+2* 1/n…n* 1/n = O(n)

改进方法:
插入:
如果数组的值是无序的,设想要插入数据的角标位置为a,取出角标a下的数组的值,放入数组的最后的位置,然后将需要插入的值放入原来a的位置。改进后时间复杂度为O(1);如果数组是有序的,那只能按照之前移动数据的方式,并不能改进和优化
删除:
如果数组的值是无序的,如果想要删除数组头部的三个元素,正常情况下每次删除都要移动剩下的元素。改进的方式是:先记录这个三个要删除的元素,当数组空间满的时候,再进行删除之前记录的元素。(JVM的标记清除算法核心思想)这样优化后,不用每次执行删除都移动元素了,但是最后数组满了进行删除的时候,还是需要遍历到数组的最后,时间复杂度是O(n)。

Java中容器类List和数组如何选择

1.数组只能存储基本数据类型,List中存储的是基本类型的包装类,使用中会涉及到装箱和拆箱操作,是有性能消耗的。如果特别追求性能,使用数组

2.数组不支持动态扩容,除非自己实现动态扩容,List支持动态扩容,如果事先数据个数已知,可以用数组

总结

数组(Array)是一种线性表数据结构,用连续的内存空间,存储相同类型的数据,特点是可以随机访问数组元素,插入数据和删除数据效率低,平均时间复杂度是O(n)。实际开发中,一般使用Java提供的容器类,当最求极致的性能比如说写网络相关的框架等,在能用数组的地方尽量使用数组。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值