数据结构:数组

数组的简介

数据结构三要素逻辑结构,存储结构以及数据运算

数组的逻辑结构:线性结构

数组的存储结构:顺序存储

数组的运算:增删改查

数组的特点

  1. 顺序存储,在内存或者硬盘中的存储地址是连续的
  2. 数组可以通过下标快速查询元素,而且下标从0开始
  3. 数组中存储的都是相同的数据类型
  4. 数组的长度在创建时便会确定,如果扩大/缩小空间只能重建数组

这些特点每一个人学习过数组的人都知道,可是为什么会有这样的特点呢?

数组特点的由来

  • 为什么数组下标从0开始

原因:方便寻址,而且寻址效率更高

解释:从0开始,那么数组中每一个元素的地址计算都有公式可言,
起始地址:数组指针的地址+下标*数据类型的长度,终止地址:起始地址+数据类型的长度

比如字符数组char a[],a指针指向的地址是0x5566,那么下标为0的元素地址是:
0x5566 + 0 * 8bit ~ 0x5566 + 0 * 8bit + 8bit

计算机借助公式可以非常方便快捷的计算每一个元素的地址,非常快捷,这也是数组可以快速访问下标元素的原因

此时有人就会提出疑问:下标从1开始也有公式啊,只需要起始地址计算时(下标-1)*长度就行啊,下标从1开始更符合人类的认知,这样不好吗?

这样我们发现,地址的计算会多一步减法的运算

计算机运行时存在大量的数组,数组相关的基本运算,我们应该追求极限效率,所以我们应该从0开始

  • 为什么数组中存储的都是相同类型的数据

因为不同类型的数据,在内存中的空间占用和表现不同,需要不同的程序进行处理

不同数据类型
int-----4byte-----32bit-----1bit符号位,32bit数据位
short-----2byte-----16bit-----1bit符号位,15bit数据位
float-----4byte-----32bit-----1bit符号位,8bit阶位,23bit数据位
double-----8byte-----64bit

假设可以存储不同的数据类型,如图:
假设可以存储不同的数据类型

10-----0*32bit~1*32bit
12-----1*32bit~2*32bit
13-----2*32bit~3*32bit
此时突然来了一个double,8byte数据,64bit,此时读取double还需要切换读取double数据类型的算法,会产生多余的开销

所以规定只能存储相同数据类型的数据

  • 为什么数组的大小在创建时就要确定

因为数组的存储地址连续
在这里插入图片描述

如果要保证存储地址连续,同时创建时不需要确定大小,那么要保证后续新增仍然能保持连续,就需要提前留下空间给后续的新增
这样的设计,留的多会造成空间浪费;
留的少,就只能被迫移动其他单元的数据,这样非常麻烦

所以不如就从一开始创建时,就保证大小固定,要扩容再重新申请,原内存空间拷贝完数据之后销毁,这样比较简单。

数组的数据运算

数组可以分为有序数组和无序数组,他们各自CURD的时间复杂度如图所示:

在这里插入图片描述

查询和新增

有序数组的查询时间复杂度是O(logn)的原因是,可以使用二分查找

无序数组的新增时间复杂度是O(1)的原因是,直接向数组末尾插入

有序数组新增的时间复杂度是O(n)的原因是,因为有序数组新增元素后依然要保持有序,需要向元素之间插入,而这种插入,会导致后续元素的移动,移动次数的数学期望是n/2,所以时间复杂度是O(n)

如果知道下标的话,不论哪种数组的查询时间复杂度都是O(1)

删除

数组元素的删除,并不是内存空间的删除,而是数据的删除,删除前后数组长度不变

涉及到中间位置的删除,就需要移动删除元素后面的元素,所以时间复杂度是O(n)

如果是末尾元素的删除,不论哪种数组的时间复杂度都是O(1)

总结

数组对查询/更改友好,对末尾新增/删除友好,对中间新增/删除不友好

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值