数据结构与算法之美 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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值