数据结构与算法之美 05 | 数组

如何实现随机访问?
数组定义: 数组(Array)是一种线性表数据结构,它用一组连续的内存空间来存储一组具有相同类型的数据。


线性表: 是最基础、最简单、最常用的一种数据结构,一个线性表是n个具有相同特性的数据元素的有限序列。
线性表中数据元素之间的关系是一对一关系,即出了第一个和最后一个数据元素之外,其他数据元素都是首尾相接。

数组、链表、队列、栈等都是线性表结构

顺序表: 是在计算机内存中以数组的形式保存的线性表,线性表采用顺序存储的方式存储就称之为顺序表。

数组和单链表区别:
1. 顺序表: 用一段连续的存储单元,依次存储线性表的数据元素
单链表: 采用链式存储结构,用一组任意的存储单元存储线性表的元素,通过指针连起来
2. 顺序表: 查询时间复杂度O(1), 插入和删除时间复杂度O(n)
单链表: 查询时间复杂度O(n), 插入和删除时间复杂度O(1)
3. 顺序表: 需要预分配存储空间,分大了浪费,小了容易发生上溢
单链表: 不需要分配存储空间,只要有就可以分配,元素个数不受限制
4. 若线性表需要频繁查找,很少进行插入和删除操作时,宜采用顺序存储结构,若需要频繁插入和删除时,宜采用单链表结构。
5. 线性表是逻辑结构,顺序表和链表都是存储结构

与线性表对应的概念是非线性表,二叉树、堆、图等被称为非线性表。


为什么数组的查询操作是O(1)?
对于数组可以直接计算出目标元素在内存中的具体位置,然后就可以直接访问:
a[k]_address = base_address + k * type_size

对于链表需要去遍历整个链表才可以得到目标元素。

对数组操作的优化:
插入. 如果数组中存储的数据没有任何规律,数组只是被当做一个存储数据的集合;
在这种情况下,可以将摸个数组插入到第k个位置,为了避免大规模的数据搬迁,
可以直接将第k位的数据搬移到数组元素的最后,把新的元素直接放入第k个位置。
删除. 在某些特殊的场景下,不一定追求数组中的数据的连续性,可以将多次删除操作集中在一起执行,
这样就避免了多次搬迁数据,每次删除的操作并不是真正的删除操作,只是记录数据已经被删除,
当数组没有更多空间存储数据时,再出发执行一次真正的删除操作。
JVM标记清楚垃圾回收算法的核心思想就是这样。


相关资料:

Slice本身是一个只读对象,其工作机制类似数组指针的一种封装(跟Python的list类似)。
Slice是对数组一个连续片段的引用,所以切片是一个引用类型。

type slice struct {
array unsafe.Pointer // 指向一个数组的指针
len int
cap int
}


Python时间复杂度 https://wiki.python.org/moin/TimeComplexity
GO语言Slice底层实现原理 https://www.jianshu.com/p/030aba2bff41
原文地址:https://www.cnblogs.com/vincenshen/p/9741705.html