储物柜的艺术:数据结构是如何让代码变整齐的?
你已经学会了用变量 a 来存放一个数字。但如果你有一百个、一万个数字呢?难道要发明一万个变量名吗?
为了处理海量的数据,我们需要更高级的“储物方案”。
第一幕:从变量到数组 —— 顺序存储
想象一下,你有一堆乱七八糟的数字(8, 12, 45, 2, 9...)。你找来一块连续的空地,把柜子排成一排,每个柜子都有编号:0, 1, 2, 3...
你要找第几个,直接看编号就行。
java
1
2
3
4
5
2
3
4
5
恭喜你,发明了“数组”。 这种背靠背、手拉手的紧凑排列,就叫顺序存储结构。它的查询速度极快,但也有它的弱点。
第二幕:从数组到链表 —— 链式存储
数组虽然找东西快,但有个致命缺点:你想在中间挤进一个人,后面所有人都得痛苦地往后挪一步。
于是你换了个思路:数字不一定要排排坐,它们可以散落在各处,只要每个人手里都牵着下一位朋友的“地址”。想插队?只需要改动两个人的手势即可。
java
1
2
3
2
3
恭喜你,发明了“链表”。 这种自由连接的方式,叫作链式存储结构,它是动态修改数据的高手。
第三幕:后进先出的栈 —— Stack
现在你有了基础的存储方式,但你还想要更简单的“规矩”。
比如洗盘子,你总是把洗好的叠在最上面,用的时候也从最上面拿。最后放进去的,最先被拿走(LIFO)。
java
Stack<String> stack = new Stack<>();
stack.push("盘子A"); // 入栈
stack.push("盘子B");
String top = stack.pop(); // 出栈,拿到的是“盘子B”恭喜你,发现了“栈”。 它是程序员的“后悔药”——你浏览器的“后退”键、文本编辑器的“撤销”功能,底层全是它。
第四幕:先进先出的队列 —— Queue
有时候,你需要绝对的公平。就像排队买奶茶,先到的先拿走,后到的只能乖乖等在后面。先进去的,先出来(FIFO)。
java
Queue<String> queue = new LinkedList<>();
queue.offer("顾客A"); // 入队
queue.offer("顾客B");
String first = queue.poll(); // 出队,拿到的是“顾客A”恭喜你,发现了“队列”。 无论是排队打印文件,还是网游里的技能施法排队,全是它的功劳。
结尾:数据支撑起的世界
从乱麻到方阵,数据结构让你的程序拥有了组织能力:
- 变量是点;
- 函数是线;
- 数据结构则是让程序支撑起复杂世界的“面”。
当你的代码越来越好、数据越来越稳,你可能会开始担心:“万一我改坏了怎么办?万一我想回到昨天的版本怎么办?”
下一站,我们要请出开源世界的时光机——“平行时空的管理者” Git。
(本文整理自《程序员的入场券》系列教程)