携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第10天,点击查看活动详情
数组&链表
数组
数组在我们开发中是最常见的一种数据结构,也是使用最多的之一。
它在内存中是通过连续的内存空间来存储,如下图所示:
在对数组的增删改查操作中,增加一个节点,改动最小的在数组尾部push一个元素,其他元素都不用变动,但如果是插入到数组头部,那其他所有元素都得往后移动一个内存单元,在极端情况下,如果连续内存不够,那还得重新分配内存地址。删除操作和新增操作类似,都可能需要移动原数组元素内存位置,时间复杂度是O(n)。改和查相对来说会比较简单,因为数组是连续的线性内存结构,查找到某个元素的时间复杂度是O(1)。
链表
单链表
相对于数组来说,链表在内存的存储空间不一定是连续的,可能是间断的,这样也没有关系,因为链表可以通过next指针来查询下一个元素,如下图所示:
链表的增删改查时间复杂度和数组很有很大区别:增删改查中,查询某元素的时间复杂度是O(n),其他操作的时间复杂度是O(1)。我们来看如下图来分析:
当我们删除目标元素Target Node的时候,只需要将前一个元素的Next指针指向Target Node的后一个元素即可。新增逻辑类似,把Next指针指向新增的目标元素,时间复杂度都是O(1)。但由于链表的元素不一定是连续的内存空间,查询某个元素的话就需要通过不断执行next来查找,时间复杂度是(n)。
双链表
双链表顾名思义,就是每个元素都有双Next指针,可以往前后两个方向进行查找。
两者的联系
数组和链表分别是连续空间和非连续空间的最基础的存储方式,它们都是线性表。其他的一些数据结构,如栈、队列、二叉树和B+树等,基本都是两者的结合或由二者演变而来。