【基础数据结构|数组】

本文详细阐述了数组的定义、插入和删除操作的复杂度优化,以及防止数组越界的方法。还介绍了Java中的容器类如ArrayList和vector,强调了它们在不同场景下的适用性和性能考虑。
摘要由CSDN通过智能技术生成

此为自己学习课程的笔记,供自己复习用。


一、数组定义

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

线性表:是指数据排成像一条线一样的结构。每个线性表上的数据最多只有前和后两个方向。
非线性表中,数据之间并不是简单的前后关系。

链表、队列、栈等都是线性表结构。
二叉树、堆、图等都是非线性结构

数组支持随机访问,根据下标随机访问的时间复杂度为 O(1)

通过寻址公式访问内存中的数据:

a[k]_address = base_address + k * type_size

二、插入和删除操作

1.插入操作

在数组的非末尾位置插入一个元素时,需要对其后面位置的元素进行移动。此时,插入操作的时间复杂度为O(n)。

例如:
假设数组的长度为 n,现在,需要将一个数据插入到数组中的第 k 个位置。为了把第 k 个位置腾出来,给新来的数据,我们需要将第 k~n 这部分的元素都顺序地往后挪一位。

为了减少插入操作的时间复杂度,可以通过如下方法巧妙的解决:
假如数组中的元素是无序的,只是被当作一个存储数据的集合,可以直接将第 k 位的数据搬移到数组元素的最后,把新的元素直接放入第 k 个位置。

这样,在第 k 个位置插入一个元素的时间复杂度就会降为 O(1)。

2.删除操作

当我们要删除第 k 个位置的数据时,为了保证内存的连续性,需要将其后面的元素全部往前移。此时,删除操作的时间复杂度为O(n)。

例如:有一个数组,依次存储着元素a, b, c, d, e, f,现在有两个删除操作,分别删除元素a和元素b。

为了防止c, d, e, f 移动两次,可以先标记好每次要删除的元素,当数组满了的时候再一起将那些要删除的元素删掉,可以降低移动带来的时间复杂度。

三、防止数组的访问越界

数组越界在 C 语言中是一种未决行为,并没有规定数组访问越界时编译器应该如何处理。

因为,访问数组的本质就是访问一段连续内存,只要数组通过偏移计算得到的内存地址是可用的,那么程序就可能不会报任何错误。

而像Java语言本身就会做越界检查。

四、容器类

Java中的 ArrayList、C++ STL 中的 vector都属于对数组的封装和扩展。

它们支持动态扩容:当要存储的数据超过了预先设定的数组的大小,就要重新分配一块更大的内存空间,将原来的数组中的数据复制过去,然后再将新的数据插入。

动态扩容涉及到内存申请和数据搬移,会比较耗时。

注意:为了减少扩容操作,在使用容器的时候最好事先指定数据的大小。


总结

对于业务开发,可以直接使用容器,虽然会损耗一些性能,但是不会对系统的整体性能造成影响。

对于底层的开发,非常注重性能的开发,此时数组要优于容器。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值