学习笔记

数据结构与算法

#数据结构与算法 #AI编程

一、我们要到哪里去?

数据结构与算法,是很多人学编程的“拦路虎”。

但在 AI 时代,我们的目标不是死磕底层实现,而是学到能听懂、能抽象业务、能让 AI 正确实现的程度。

当你看完这篇,你应该能回答:

  1. 为什么要学数据结构与算法

  2. 数据结构有哪些、各自解决什么问题

  3. 常见算法的逻辑与应用场景

  4. 如何用 AI 在项目中快速调用这些“工具”

更重要的是,你能用生活例子把它们讲出来——因为它们本就是从现实抽象出来的。


二、AI编程速查表

结构/算法特点生活例子编程场景常用接口
数组 Array有序存储,可按下标访问排好号的座位表列表展示、分页数据push, pop, index
对象 Object键值对存储身份证信息用户信息、配置key访问
队列 Queue先进先出 FIFO排队买票消息队列、任务调度enqueue, dequeue
栈 Stack后进先出 LIFO叠盘子撤销功能、函数调用push, pop
树 Tree分层结构组织架构图菜单、分类、权限系统遍历、插入
图 Graph节点+关系社交网络路径规划、依赖关系邻接表、遍历
排序数据按规则排列排座位价格排序、时间排序sort
搜索找到目标元素查字典关键字搜索find, filter
遍历逐个访问数据点名数据处理forEach, map
贪心每步选最优找零用最大面额资源分配
动态规划分解子问题旅行计划成本优化、调度

用法心法:先认出问题类型 → 找到匹配结构/算法 → 用 AI 生成 → 自己验证。


二、抽象的程度

汽车,对司机和修理工来说,是两种完全不同的存在。

  • 修理工看到的是液压系统、传动装置、发动机结构。

  • 司机看到的只是方向盘、油门、刹车和一个密闭的驾驶空间。

对司机来说,汽车就是一组接口(Interface):转动方向盘、踩油门,车辆就会按预期行驶。至于发动机内部是如何运转的,他完全不用关心。

编程也是如此。用户只在乎界面上的按钮和操作效果,而作为编程者,我们要设计出内部的逻辑,让这些按钮真正发挥作用。这就是抽象:隐藏复杂的实现细节,只暴露必要的操作接口。

程序员圈里有句老话:“不要重复造轮子”。意思是,如果你想让汽车跑起来,没必要自己打铁造轮胎——先看看有没有现成的轮子可以直接用。事实上,大多数复杂功能,别人已经写好并放在代码仓库中,我们只需调用即可,那些仓库就是一种抽象。

本节课同样是一个“抽象版本”的学习——我们不会去从零写出所有实现,而是学会识别、选择并调用已有的工具库,必要时让 AI 帮我们完成具体代码。


三、简单与复杂数据结构

数据,我们每天都在接触。

但如果要对它们分类呢?毕竟世界无限,而我们的描述能力有限,我们必须给这些数据贴上标签。

在业务场景中,你可能会遇到这样的信息:

  • 用户姓名

  • 订单日期

  • 金额

  • 是否付款

这些都是基本数据类型

字符串(String)、日期(Date)、数值(Number)、布尔值(Boolean,表示是/否)


但是,只靠这些基本类型够吗?

假如你有 10 个订单,如何管理它们?一个聪明的做法是,把每个订单的信息打包在一起,例如:

订单1:
{
  用户姓名: "Gobi Cowboy",
  地址: "天宫一号",
  日期: "20xx-xx-xx",
  金额: "¥1,000,000,000.00"
},
订单2:
{
  用户姓名: "张三",
  ...
},
...
订单10:
{
  用户姓名: "李四",
  ...
}

恭喜你,这其实就是对象(Object)

类似地,如果要存很多数字,可以用数组(Array)

array = [1, 2, 3, 2, 1]

使用这些复杂数据类型时,我们无需关心它的底层结构,只需通过**接口(Interface)**操作:

// 数组示例
arr = [1, 2, 3, 1, 1, 2]
arr[0] // 查找第1个元素(下标从0开始) → 1
arr[2] // 查找第3个元素 → 3

// 对象示例
obj = {
  用户姓名: "Gobi Cowboy",
  地址: "天宫一号",
  日期: "20xx-xx-xx",
  金额: "¥1,000,000,000.00"
}
obj.金额 // 读取金额 → ¥1,000,000,000.00

总结

复杂数据类型就是对简单数据类型的一种封装

它们让我们能更方便地组织和管理信息,而不用每次都从零开始构建结构。


四、常见的封装数据结构

如果你以为上面的数据结构可以解决我们的问题,那你就too young too simple了。接下来,我们将了解一些复杂的数据结构,而这些数据结构也是我们这堂课的主要对象。

1.队列(queue):

1.1 场景:

想象订单发货流程:必须按下单时间顺序来,一单一单处理,不能乱发。

如果每次都要人工找“下一个日期的订单”,不仅繁琐,还容易出错——于是,队列应运而生。

1.2 理论:

队列的特点:

  • 先进先出(First in First out— FIFO)
  • 只能从末尾插入
  • 只能从前端弹出

队列开放的接口有以下四个:

  • 入队(enqueue)
  • 出队(dequeue)
  • 查看队首(peek)
  • 是否为空(isEmpty)

1.3 例子:

在计算机的世界里,微信发出的消息队列,网页上执行的事件循环(后面我们会讲到),广度优先搜索算法(BFS)储存的节点(后面会讲到)

现实生活中,例如马路上红绿灯路口的汽车,排队买票都是这样的例子。

那你的现实中,有没有其他的队列的例子呢?

1.4 小小的问题

如果队列中有插队的如何处理——可以查询‘优先级队列’

如果在超市,排队,我在末尾不想排了,或者有一个人直接结账了 ——可以查询‘双端队列’

2. 栈(stack)

2.1 场景:

我们来做一个思想实验:

假设你正在专心学习本教程,宝宝突然大哭 → 你去哄宝宝;

这时厨房水龙头又爆了 → 你去找修理工。

任务的执行顺序变成:

找修理工(最后发生 → 先处理)→ 哄宝宝 → 继续学习。

这是一个现实生活中的问题,但大家有没有发现和队列的区别,栈中最后的事情却要最先完成。

大家可以想想盘子的操作,最上面的盘子最先被使用。

2.2 理论:

栈的特点:

  • 后入先出(Last in First out — LIFO)

开放的接口:

  • 压栈(push)
  • 出栈(pop)
  • 栈顶(peek)
  • 是否为空(isEmpty)

2.3 例子:

这种反直觉,我们称之为次序反转。

在计算机的世界应用非常的广泛,例如,递归(后面会讲到),浏览器的后退问题,括号的匹配问题,深度优先搜索(DFS,后面会讲到)等

在现实中,例如叠盘子,套娃(最里面的娃先开),文件的保存(放在最上面的是最先被使用的)

你发现了什么现实的例子呢?请记得打在评论区。

2.4 小小的问题

如果栈底的盘子一直没用,会落灰怎么办?(提示:这涉及队列与栈混合结构

3. 树(Tree)

3.1 场景

假设你是一家几千人公司的 CEO,要画一张组织架构图。

用我们之前的数组对象能不能表达?

——能,但很别扭。

因为公司不是扁平结构,而是有层级

CEO → 总监 → 经理 → 小组长 → 员工。

一个员工只会有一个直接上司,但上司可以管理多人。

这种一对多、上下分层的关系,就需要用到一种全新的结构:

为什么叫“树”?把组织架构图倒过来看——CEO 是“树根”,员工是“树叶”,层层分支,形象吧?


3.2 理论

树是用来描述层级关系一对多关系的数据结构。

它有几个特点:

  • 根节点(Root):唯一的顶层节点(CEO)

  • 子节点(Children):下属节点(经理的组员)

  • 父节点(Parent):每个节点只能有一个直接上级

  • 叶子节点(Leaf):没有下属的节点(普通员工)

  • 无环性(No Cycle):不能既是上司又是下属

常用操作接口:

  • 添加节点(Add Node) → 招新人

  • 删除节点(Remove Node) → 离职

  • 查找节点(Find Node) → 找“张三”

  • 遍历(Traverse) → 打印全员名单


3.3 例子

  • 计算机世界:文件系统(文件夹-文件)、网页 DOM 结构、AI 决策树

  • 现实生活:公司组织架构、家族族谱、书籍目录结构

3.4 思考题

如果 CEO 想快速找到“张三”,并且知道他所在的部门和直接上司,用什么搜索方法最有效?

(提示:这涉及树的遍历算法

4. 图(graph)

4.1 场景

树结构很强大,但能解决所有问题吗?

想象你要规划城市的地铁线路图:

  • “人民广场”站连接 1 号线、2 号线和 8 号线

  • 你从“人民广场”出发,绕 2 号线一圈,还能回到“人民广场”

这里有两个特征:

  1. 多对多关系(一个站点连接多个站点)

  2. 存在环(走一圈又回到起点)

树结构只能处理单一层级、无环的关系,这种更复杂的网络,就需要更强大的结构——图(Graph)


4.2 理论

图是用来描述多对多关系的最通用数据结构,树其实是没有环的特殊图

组成

  • 节点(Vertex):实体,如城市、地铁站、网页

  • 边(Edge):连接节点的关系

    • 无向边(Undirected):双向关系(微信好友)

    • 有向边(Directed):单向关系(微博关注)

    • 带权重的边(Weighted Edge):边附带距离、时间、价格等信息

常用接口

  • 添加/删除节点(Add/Remove Vertex)

  • 添加/删除边(Add/Remove Edge)

  • 查找相邻节点(Get Neighbors)

  • 查找路径(Find Path)

  • 遍历图(DFS、BFS)


4.3 例子

  • 计算机世界

    • 社交网络(用户=节点,好友关系=边)

    • 互联网(网页=节点,超链接=边)

    • 推荐系统(商品=节点,“也喜欢”关系=边)

  • 现实生活

    • 地铁线路图

    • 航空航线图

    • 物流配送网络

    • 人际关系网络(“六度空间理论”)

    • 疾病传播路径


4.4思考题

如果你在北京,要去广州出差,路线可以飞机、高铁、甚至多次中转。面对这张城市(节点)+ 交通线路(带价格权重的边)组成的图,如何找到最低成本的出行方案?

(提示:Dijkstra 算法会帮你)