数据结构:数组、链表、栈、队列
数据结构就是安排数据的方式,让程序能又快又方便地使用数据。
- 数组:大小固定,数据挨着放,用下标就能直接找到任何一项(a[3])。在中间插入很慢。
- 链表(动态):每个结点保存一个值和指向下一个结点的链接。它可以按需要变长或变短,但要找第5项,必须从第1项一路走到第4项。
- 栈:只在一端放入(push)和取出(pop)(LIFO)。用于撤销、后退按钮和检查括号。
- 队列:从队尾加入,从队头取出(FIFO)。用于打印任务和排队。
库里已经有这些工具。在Python中,list可以当栈用(append、pop),collections.deque可以当快速队列用。有现成的库就直接用,不要重新写。
stack = []
stack.append(5); stack.append(8)
stack.pop() # gives 8
from collections import deque
q = deque([4, 9]); q.append(2)
q.popleft() # gives 4
使用IDE:编写、运行、测试
IDE(集成开发环境)把编辑器、运行按钮、调试器和各种工具放在同一个地方。它会给代码上色、提示名字,还会在你输入时显示错误。
- 运行程序,看输出结果。
- 测试:用简单的、普通的和刁钻的输入(空列表、零、非常大的数)。
- 调试:设置断点,一行一行地执行,观察变量的变化。
2D和3D可视化与动画
图像能帮我们看出规律。程序可以画图表(柱状图、折线图、散点图)、2D图形和3D场景。动画就是把同一幅画一遍又一遍地重画,每次只改变一点点(每秒大约30到60次)。简单的做法是:用一个变量,比如x,每一帧给它加一点,然后重画。本页的3D也是这样用3D库做出来的。
进阶电子表格函数
电子表格可以用函数完成像编程一样的工作:
IF(B2>=50,"Pass","Fail")在两个结果中选一个。SUMIF(B2:B5,">=50")只把符合条件的单元格相加;COUNTIF则是数一数有几个。VLOOKUP(2, A2:B5, 2, FALSE)在第一列里找2,然后返回同一行第2列的值。XLOOKUP做同样的事,但更容易用。- 数据透视表可以把大量数据按组汇总,图表则把结果画出来。
关系数据库与SQL
关系数据库把数据放在由行和列组成的表里。每张表都有一个主键,这一列的值各不相同(比如id)。另一张表把这个值当作外键,用来连回这张表。好的设计让每个事实只存一次,这样就没有重复的数据。
SQL是用来提问和修改数据的语言:
SELECT name, score FROM students
JOIN marks ON students.id = marks.id
WHERE score >= 50 ORDER BY score DESC;
INSERT INTO marks (id, score) VALUES (5, 67);
UPDATE marks SET score = 55 WHERE id = 2;
DELETE FROM marks WHERE id = 5;完整性是指数据始终正确:键是唯一的,外键必须对应一个真实存在的行,值的类型也必须正确。安全是指给用户设置密码,只给每个用户需要的权限,做好备份,而且绝不能把用户输入的文字直接拼进查询语句(要用参数),这样才能防止SQL注入。
为开放资源做贡献
很多工具和库是开源的:任何人都可以在许可证的规定下阅读、使用和改进它们。你可以修复一个错误、改进一份指南、翻译一个页面或者添加一个例子来帮忙。一定要先读许可证,注明来源,提出修改建议时要把话写得清楚而有礼貌。
试一试
在3D的第5步里,往栈里放入3个数据,再把它们取出来,写下顺序。队列也这样做一遍。然后先预测,再检查:加入4、9、2,再取出一个以后,队列的队头和栈的栈顶分别是哪个值?
重点公式和概念
- 栈 = LIFO(后进先出):push、pop。
- 队列 = FIFO(先进先出):enqueue、dequeue。
- 数组:大小固定,用下标访问。链表:大小可变,顺着链接查找。
- SELECT columns FROM table WHERE condition
- 主键 = 唯一的id。外键 = 指向另一张表的链接。
例题讲解
1. 数据5、8、2按这个顺序压入栈。然后做两次pop。现在栈顶是什么?
压入后的栈:5、8、2(2在最上面)。pop先取走2,再取走8。剩下:5。栈顶 = 5。
2. 数据4、9、2按这个顺序加入队列。做一次dequeue。现在队头是哪一个?
最先进去的先离开,所以4被取走。队头是9。
3. 成绩表:id 1到4,分数是72、45、88、51。WHERE score >= 50 会返回多少行?
72、88和51不低于50。所以是3行。
4. 单元格B2:B5里是72、45、88、51。=SUMIF(B2:B5,">=50") 的结果是多少?
只把72、88和51相加:72 + 88 + 51 = 211。
5. 为什么可以用栈来检查表达式里的括号,比如 ( [ ] )?
每遇到一个左括号就压入栈。遇到右括号时,就弹出一个并检查它们是否配对。最近的左括号必须最先被关上(LIFO),而这正是栈的特点。如果最后栈是空的,括号就是配对的。
常见错误
- 事先不知道大小,却用了数组。用列表或链表更好。
- 把栈和队列搞混。栈取走最新的;队列取走最旧的。
- 在UPDATE或DELETE里忘了写WHERE,结果每一行都被改了。
- 把用户输入的文字拼接进SQL字符串。应该改用参数。