数据结构与算法-学习笔记(二)

数组

定义:数组(Array)是一种线性表数据结构。它用一组连续的内存空间,来存储一组具有相同类型的数据(不同语言对数组的定义标准不同,大多数语言要求同类型,而在JavaScript中,数组中元素可以是不同类型)。

解释:
1. 线性表
顾名思义,就是数据排成一条线一样的结构。每个线性表上的数据最多有前后两个方向。除了数组之外,链表、队列、栈等也是线性结构。与之对应的就是非线性表:数据之间不是简单的前后关系。
复制代码

 2. 连续的内存空间和相同类型的数据
 数组内的元素所占用的内存空间相同且连续,正因为这两点限制,数组才有了——随机访问——的特性。我们知道计算机会给每个内存单元(1B)分配一个内存地址,通过地址来访问。当计算机要随机访问数组中的某个元素时,首先得找出该元素的内存地址,通过下面的寻址公式来计算:a[i]_address = base_address + i * data_type_size
 要注意的点:数组适合查找,查找的时间复杂度为O(1)。是不准确的。正确的说法:数组支持随机访问,根据下标的随机访问时间复杂度是O(1),仅需执行寻址一行寻址公式就可找到。
复制代码

低效的插入删除
插入:

为保证数组数据的连续性,在第k个位置上插入数据,如要保证数组元素顺序不变,则k~n这部分数据都需要往后移一位,此时k=n-1,最好的时间复杂度O(1),k=0,最坏的时间复杂度O(n)。每个位置插入的概率是一样的1/n,所以平均时间复杂度(1+2+...+n)/n = O(n)。 如果不需要保证顺序:

此时O(1)。

删除:

同理插入每删除一次,保证顺序不变,则平均时间复杂度O(n)。如果在某些场景中,不一定要保证数组中数据的连续性。则可以将多次删除操作集中一次执行。每次要删除的数据都进行标记,当数组没有更多空间存储数据时,触发一次真正的删除操作。

警惕数组的访问越界问题:

这段C语言代码:C中只要不访问受限内存,所有内存空间都可以自由访问。

这段代码可能由于编译器的不同,造成结果也是不同的。1. 无限循环:根据数组的寻址公式可以知道数组a[0]~a[n-1]地址是越来越大的,栈中是从高地址向低地址增长的,因此内存排布应该是i,a[2],a[1],a[0]。访问a[3]也就等于i(前提都是相同类型数据)。2.打印4次(xcode):编译器开启堆栈保护(防止溢出漏洞如下图,通过溢出修改内存中其他区域)
开启保护后,可能会改变函数栈中变量的内存分配:数组在其他变量之前,先分配
这样数组越界就不会覆盖其他变量了。除了堆栈保护会影响结果外,CPU的字节对其也会影响结果。 C语言需要开发者注意数组越界问题,其他语言如OC,运行时会报错。

数组下标为什么从0开始

解释:

  1. 下标确切定义应该是‘偏移量’,a[1]:偏移了一个位置。这样寻址公式:a[k]_address = base_address + k * type_size 如果从1开始:a[k]_address = base_address + (k-1)*type_size多了一步计算k-1。
  2. 历史原因,最开始就设计从0开始,后边的语言就一直沿用了。

转载于:https://juejin.im/post/5bc9b7785188255c59673c12

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值