数据结构快速入门:数组与链表、栈与队列之间的关系

写这篇文章主要是想简单综述一下数据结构里的底层逻辑。整篇文章没有对源码的分析,只是把这些概念同生活中的具体实例简单类比一下,方便理解。先上图:
基于数组与链表的延申关系图

一、内存里的两种积木

想象一下,内存就像一个巨大的乐高玩具箱,我们有两种积木可以用来搭建东西:

1. 数组:整齐排列的储物格

数组就像是超市里的一排储物格,每个格子都编了号,而且紧紧挨在一起。这种结构的好处是:

  • 找东西快:只要知道编号(索引),直接就能找到对应的格子
  • 省空间:格子之间没有空隙,内存利用率高
  • 缺点:如果中间的格子要拿走或者添加东西,后面的格子都得跟着挪动

2. 链表:用绳子串起来的珠子

链表就像是用绳子串起来的珠子,每个珠子上都写着下一个珠子在哪里。这种结构的好处是:

  • 灵活插入:想在哪里加珠子或者减珠子,直接剪断绳子就行
  • 动态扩展:珠子不够了随时可以加,不需要提前准备很多
  • 缺点:找特定的珠子得从头开始一个一个数

二、基于这两种积木的玩法

有了这两种积木,我们可以玩出不同的花样。最常见的两种玩法就是栈和队列,它们代表了两种不同的游戏规则。

1. 栈:像叠盘子一样的游戏

栈这个东西,就像是我们在家里叠盘子。最后放上去的盘子,总是第一个被拿走:

  • 后进先出(LIFO):最后放进去的东西最先出来
  • 只能操作顶部:就像叠盘子,只能从最上面拿或者放
数组栈:固定大小的盘子架

如果用数组来实现栈,就像是有一个固定大小的盘子架:

  • 优点:操作简单,不需要额外的空间
  • 缺点:盘子架满了就放不下了,得换一个更大的架子
链表栈:无限扩展的盘子链

如果用链表来实现栈,就像是用绳子串盘子:

  • 优点:盘子可以无限加,只要有足够的绳子和盘子
  • 缺点:每个盘子都得额外拴一根绳子,有点浪费

2. 队列:像排队一样的游戏

队列就像是我们在超市排队结账,先到的人先结账:

  • 先进先出(FIFO):第一个排队的人第一个离开
  • 两头操作:一头进人,一头出人
数组队列:循环使用的排队通道

用数组实现队列时,为了不浪费空间,我们可以把排队通道设计成循环的:

  • 就像操场的跑道,跑完一圈可以接着跑下一圈
  • 需要两个指针,一个指向队头,一个指向队尾
链表队列:灵活伸缩的排队链

用链表实现队列时,排队的人可以随时加入或者离开:

  • 优点:队伍可以无限长,只要有足够的空间
  • 缺点:每个人都得知道下一个人是谁,有点麻烦

三、实际场景中的选择

在实际编程中,我们怎么选择用哪种实现方式呢?这得看具体情况:

1. 数组实现的场景

  • 如果我们知道最多会有多少个元素,比如扑克牌只有54张
  • 如果我们需要频繁地随机访问元素,比如查字典
  • 如果内存比较紧张,需要高效利用空间

2. 链表实现的场景

  • 如果元素数量不确定,比如网站的访问日志
  • 如果需要频繁地插入和删除元素,比如编辑器的撤销操作
  • 如果内存不是问题,更看重操作的灵活性

四、扩展玩法

除了基本的栈和队列,我们还可以玩出更多花样:

1. 双端队列:两头都能操作的队列

双端队列就像是一个可以两头进出的隧道,既可以从前面进,也可以从后面进。

2. 优先级队列:VIP优先的队列

优先级队列就像是机场的VIP通道,有特权的人可以优先通过。

3. 并发队列:多个人同时操作的队列

在多线程编程中,我们经常需要多个线程同时操作一个队列,这时候就需要特殊的并发队列。

五、总结

数据结构的层次架构:从底层存储到高层抽象
通过这篇文章,我们用大白话解释了数据结构的底层逻辑:

  1. 数组和链表是内存中的两种基本存储方式
  2. 栈和队列是基于这两种存储方式的逻辑抽象
  3. 不同的实现方式有不同的优缺点,适用于不同的场景

理解这些底层逻辑,就像是掌握了编程世界的基本法则。在实际开发中,我们可以根据具体需求选择最合适的数据结构,从而写出高效、优雅的代码。希望这篇文章能帮助你更好地理解数据结构,谢谢阅读!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值