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

相关文章
|
6天前
|
机器学习/深度学习 算法
|
4月前
|
机器学习/深度学习 算法
【文献学习】Meta-Learning to Communicate: Fast End-to-End Training for Fading Channels
把学习如何在衰落的噪声信道上进行通信的过程公式化为对自动编码器的无监督训练。该自动编码器由编码器,信道和解码器的级联组成。
41 2
|
7月前
|
机器学习/深度学习 人工智能
【CatBoost报错解决】CatBoostError: Bad value for num feature[non default doc idx=0,feature idx=19]=
【CatBoost报错解决】CatBoostError: Bad value for num feature[non default doc idx=0,feature idx=19]=
|
机器学习/深度学习 自然语言处理 算法
ACL 2022:Graph Pre-training for AMR Parsing and Generation
抽象语义表示(AMR)以图形结构突出文本的核心语义信息。最近,预训练语言模型(PLM)分别具有AMR解析和AMR到文本生成的高级任务。
159 0
|
搜索推荐 索引
Term Suggester 中 suggest_mode 的三种模式missing、popular、always 的区别
Term Suggester 中 suggest_mode 的三种模式missing、popular、always 的区别
|
异构计算
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“
成功解决_catboost.CatBoostError: Invalid cat_features[4] = 8 value: index must be < 8.
成功解决_catboost.CatBoostError: Invalid cat_features[4] = 8 value: index must be < 8.
|
机器学习/深度学习 算法 数据挖掘
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》的翻译与解读
Data Structures and Algorithms (English) - 6-2 Two Stacks In One Array(20 分)
Data Structures and Algorithms (English) - 6-2 Two Stacks In One Array(20 分)
142 0