Learning algorithem the hard way array (part 2)

简介: 数组(Array)是一种线性表数据结构。它用一组连续的内存空间来存储一组具有相同数据类型的数据。上述定义当中有有几个较为关键的概念:线性表 (Linear List)线性表是指数据排成一个线型的结构。

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

上述定义当中有有几个较为关键的概念:

线性表 (Linear List)
线性表是指数据排成一个线型的结构。每个线性表上的数据最多只有前后两个方向。

除了数组之外,链表、队列、栈也是线性表结构。
11
而与其对应的概念是非线性表,例如二叉树、图、堆等。
22
连续的内存空间和相同的数据类型
数组的随机访问(根据索引下标访问)时间复杂度为 O(1) 。其随机访问的实现原理是:

a[i]_address = base_address + i * data_type_size

为什么大部分编程语言的数组下标是从 0 开始设计,而不是从 1 开始?
我们来思考另外一个问题,为什么大部分编程语言的数组索引下标是从 0 开始,而不是从 1 开始?如果从 1 开始的话,上述的公式必须转化为:

a[i]_address = base_address + ((i - 1) * data_type_size)

对比从 0 开始的方案,需要多做一次减法运算。因此大部分编程语言都选择从 0 开始作为数组的初始下标。

低效的插入和删除操作

插入操作
假设数组的长度为 n ,我们需要将新元素 e 插入到数组中的第 k 个位置,那我们需要将后续的 n - k 个元素顺序地往后进行移动,因此在这种场景下插入操作的时间复杂度为 O(n) 。

但是有一种特殊场景下:数组仅仅作为一种容器去存储数据,而不用关心数组中存储元素的顺序,能够将数组插入操作的算法复杂度提升为 O(1) 。

举个例子,假设数据 a[10] 中存储了 5 个元素: a、b、c、d、e 。我们将元素 x 插入到第三个位置,只需要将原有的第三个元素 c 移动到最后,再将第三个元素替换为 x ,具体的实现代码如下:

a[5] = c;
a[2] = x;

33

删除操作
与插入操作类似,如果我们要删除第 k 个位置的数据,为了内存的连续性,也需要搬移数据,因此数组的删除操作时间复杂度为 O(n) 。

有一种数组删除操作的优化方案是,不需要每一次删除操作时都移动数据,而是先将被删除的索引位置记录下来,等到数组容量不足时,再一次性地从内存当中移除数据,并移动剩余元素的位置。其核心思想与 JVM 的标记清除内存回收算法非常相似。

数组与容器类型的对比

许多编程语言中都提供了高级的容器类型,例如 Java 的 ArrayList , C++ 的 Vector 等,数组与这些高级容器类型相比,有哪些适合的应用场景了?

适合使用容器类型的场景
高级容器类型支持动态扩容,适合存储元素的大小无法事先确定的场景。例如 ArrayList 会在存储空间不足时,自动扩容 1.5 倍。需要注意的是,我们应该养成设置 ArrayList 初始容量的习惯,因为这样能够节省掉很多次内存分配空间和数据搬移的操作。

//假设从 db 当中获取用户的数据为 10000条
//指定初始容量为 10000 会比不指定容量获得更好的性能
ArrayList<User> list = new ArrayList<User>(10000);
for (int i = 0; i < db.getUserList(); i++) {
    list.add(db[i]);
}

适合使用数组的场景
ArrayList 无法存储基本类型:int 、long 等,只能存储包装类型: Integer 、Long ,而 Boxing 和 UnBoxing 会有一定的性能损耗,如果特别关注性能,就可以使用数组。

Java implemention
初步实现了类似于 ArrayList 的代码。ref here

JDK 1.8 ArrayList 的实现代码。ref here

相关文章
|
5月前
|
算法 数据挖掘
文献解读-Consistency and reproducibility of large panel next-generation sequencing: Multi-laboratory assessment of somatic mutation detection on reference materials with mismatch repair and proofreading deficiency
Consistency and reproducibility of large panel next-generation sequencing: Multi-laboratory assessment of somatic mutation detection on reference materials with mismatch repair and proofreading deficiency,大panel二代测序的一致性和重复性:对具有错配修复和校对缺陷的参考物质进行体细胞突变检测的多实验室评估
38 6
文献解读-Consistency and reproducibility of large panel next-generation sequencing: Multi-laboratory assessment of somatic mutation detection on reference materials with mismatch repair and proofreading deficiency
|
6月前
|
机器学习/深度学习 算法
【文献学习】Meta-Learning to Communicate: Fast End-to-End Training for Fading Channels
把学习如何在衰落的噪声信道上进行通信的过程公式化为对自动编码器的无监督训练。该自动编码器由编码器,信道和解码器的级联组成。
48 2
|
9月前
What value should kernel parameter AIO-MAX-NR be set to ?
What value should kernel parameter AIO-MAX-NR be set to ?
74 0
|
人工智能 编解码 自然语言处理
论文解读:Inpaint Anything: Segment Anything Meets Image Inpainting
论文解读:Inpaint Anything: Segment Anything Meets Image Inpainting
464 0
|
异构计算
Re12:读论文 Se3 Semantic Self-segmentation for Abstractive Summarization of Long Legal Documents in Low
Re12:读论文 Se3 Semantic Self-segmentation for Abstractive Summarization of Long Legal Documents in Low
Re12:读论文 Se3 Semantic Self-segmentation for Abstractive Summarization of Long Legal Documents in Low
成功解决lightgbm.basic.LightGBMError: Parameter max_depth should be of type int, got “0.02“
成功解决lightgbm.basic.LightGBMError: Parameter max_depth should be of type int, got “0.02“
|
机器学习/深度学习 算法 数据挖掘
Paper:He参数初始化之《Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet C》的翻译与解读
Paper:He参数初始化之《Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification》的翻译与解读
|
SQL Oracle 算法
Adaptive and Big Data Scale Parallel Execution in Oracle
在上篇文章中,主要讨论了SQL Server的MPP数仓系统PDW的分布式优化过程,PolarDB的并行优化从中有所借鉴,本篇文章主要看下这篇介绍Oracle并行执行策略的paper,因为在PolarDB的分布式执行策略中,有很多与其有所重叠。
238 0
Adaptive and Big Data Scale Parallel Execution in Oracle
关于Visits, Visitors, Time on Page,www9992019com-Time18122221111 on site, Bounce Rate, Exit Rate, Conversion Rate, Engagement8个重要指标的梳理
Menu 行业动态 每周更新 技术杂谈 关于我们 网站数据分析八大指标 281171 关于网站分析的8个重要指标的梳理,包括Visits, Visitors, Time on Page, Time on site, Bounce Rate, Exit Rate, Conversion Rate, Engagement。
1716 0
|
算法 搜索推荐
Learning algorithem the hard way begining (part 1)
10000 小时法则 根据《异类-不一样的成功启示录》一书中的描述,要想在任何一个领域当中称为专家,都必须经过 10000 小时的刻意练习。具体的方法包括: Chunk it up将待学习的领域切分为细化的知识点。