数组的结构是什么样子的,又是怎么操作的(第三天)

第三天,坚持不易,再难也要坚持!

什么是数组?

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

关键词解释:

  • 线性表:就是数据排列成像一条线一样的结构。每个线性表上的数据最多只有前和后两个方向。
  • 连续的内存空间:申请的数组大小,在内存上是一块连续的内存,物理上的连续。
  • 相同类型数据:这个就是字面意思了,如果是int 类型的数字,就全部是int 类型的数字。

根据数组的定义,我们知道,数组具有随机访问的特性(即可以随机选择下标进行数据访问),但是也因为它为了保证连续性,增加和删除就需要做大量的数据搬移工作,也因为他需要的是一个连续的内存空间,所以假设我们的剩余的内存大小超过100MB,但并不是连续的内存,此时我们申请100MB 大小的数组,就会失败。这是根据以上定义我们可以了解的信息。

低效的插入

数组的插入我们分为两种情况,来分析一下它的复杂度情况

  • 数组是有序的

    数组a[10] 中有a、b、d、e、f,此时我们要插入c ,就需要把c 放在的d 的位置,d、e、f 这三个元素统一往后移,即a、b、c、d、e、f。

    最好情况时间复杂度:O(1)。插入正好是在最后一位。

    最坏情况时间复杂度:O(n)。插入在第一位。

    平均情况时间复杂度:O(n)。

  • 数组是无序的

    数组a[10] 中有a、b、c、d、e,此时我们要在第三个位置插入x ,我们可以把x 放在第三个位置,第三个位置上的c 放到最后一个位置上,即a、b、x、d、e、c。

    时间复杂度:O(1)。

低效的删除

假设有一个数组大小为n,我们要删除第k 个元素,因为数组是一个连续的内存空间,为了保证数组的连续性,我们就需要将第k + 1 ~ n 中的元素都向前移一位。

它的时间复杂度为O(n)。

想一下,有没有什么办法能够优化数组的删除操作的?

如果我们一次删除数组的第一个元素,第二个元素,第三个元素,那么我们删除第一个元素时,后面的元素需要统一移动,删除第二个元素时,后面的元素也需要统一移动,删除第三个元素时,还是需要移动后面的元素,这样我们就移动了三次,就非常的繁琐了。

我们可以这么做,来降低数组搬移的操作次数。我们还是要删除前三个元素,但是在操作删除的时候,我们并不真正的去删除元素,而是对该元素进行一个标记操作。新增元素的时候,我们照常添加,当添加元素的时候,该数组已满,此时我们再去真正删除被标记的元素,就会减少数据搬移的操作次数。学java 的同学是不是对这个优化办法有点儿熟悉,没错jvm 的垃圾清楚用到了这个思想,不了解的同学可以去查一下了。

容器和数组该如何选择

针对数组类型,很多语言都提供了容器类,我只说java 中的容器类型,ArrayList。

那么问题来了?

在实际开发中,什么时候选择容器,什么时候选择数组呢。

说一下两者的优势:

  • ArrayList:将很多数组的操作细节封装起来,比如数组插入、删除时需要搬移其它数据。另外还有一个优势,支持动态扩容。
  • 数组:使用基本类型的时候可以选择数组。Java ArrayList 无法存储基本类型,比如 int、long,需要封装为 Integer、Long 类,而 Autoboxing、Unboxing 则有一定的性能消耗

总结:对于业务开发,直接使用容器就足够了,省时省力。损耗一丢丢的性能,完全不会影响到系统的整体性能。如果做底层开发,数组就更合适了。

日常:今天去逛了车展,本着去看迈腾、雅阁和凯美瑞的,结果到了车展只有两个不大的展厅,只见到了一个凯美瑞,其它两个车根本没有,不过逛了整个车展,对两个车产生了兴趣,一个是沃尔沃的S60,一个是吉利的星瑞,贼尴尬的是,沃尔沃的销售给我价格砍了又砍,在砍到我们中意的价格之后,并没有订车,然后给我又是发微信,又是打电话的,我都没好意思接电话和回复。毕竟买车是大事,超了这么多的预算,还是可以理解的哈,可惜了那个销售大哥,还得挨骂。明天周末的最后一天了,这一天一天过的可真快!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值