我的第一本算法书 第一章
第1章 数据结构
1.1
决定数据顺序和位置关系的是数据结构
电话簿的数据结构
按获取顺序排序 | 按拼音顺序排序 |
---|---|
添加简单 查询麻烦 | 查询简单 添加麻烦 |
两者结合
分别使用不同的表存储不同的首字母, 再将同一张表中的数据按获取顺序进行排序
选择适合的数据结构可以提高内存的利用率
1.2 链表
- 线性排列, 数据的添加和删除方便, 访问消耗时间
- 链表的每个数据都都有一个指针且这个指针指向下一个数据的内存地址
- 分散存储于内存中,无须在连续空间内
- 链表要访问数据, 需要按照指针方向顺序访问
- 添加数据改变指针前后指向
- 删除改变指针指向
访问:O(n) 添加.删除:O(1)
补充:
- 循环链表:链表尾部指针指向链表头. 链表变成环形
- 双向链表:每个数据有前后两个指针.
- 缺点:指针数增加导致存储空间需求增加
- 缺点:添加和删除数据需要改变更多指针指向
1.3 数组
- 也是线性排列的数据结构. 访问简单, 添加和删除费时
- 数组存储在连续空间内
- 数组中的每个数据可以根据下标算出, 就可以直接访问目标数据 (随机访问)
- 在数组中间添加或删除元素需要将后面的元素逐个移动再写入需要添加或删除的数据
访问O(1) 添加.删除O(n)
补充:
访问 | 添加 | 删除 | |
---|---|---|---|
链表 | 慢 | 快 | 快 |
数组 | 快 | 慢 | 慢 |
1.4 栈
- 线性排列
- 后进先出(Last In Fist Out, LIFO) 入栈(push) 出栈(pop)
应用场景:只需要访问最新数据. 深度优先搜索算法
1.5 队列
- 线性排列
- 先进先出(First In First Out, FIFO) 入队 出队
应用场景:先来的数据先处理. 广度优先搜索算法
1.6 哈希表
- 键值组成的数据 (键, 数据的标识符. 值, 数据的内容)
- 哈希函数计算变量值, 再将求余数. 得到的结果作为数组的下标存放
- 当发生哈希冲突时, 在数组下标的同一位置使用链表继续存储新的数据
开放地址法:发生哈希冲突时, 即刻计算一个候选地址, 如果还有冲突就再次计算另一个候选地址, 直到有空地址为止.
线性探测法
1.7 堆
-
图的树形结构, 用于优先队列(priority queues) 广度优先算法
-
子结点一定大于父结点. 最小值被存在顶端, 添加数据时, 新数据在最下面一行的左侧. 当下一行没有多余空间, 就再往下另起一行, 把数据加在这一行的最左端.
-
父结点大于子结点就要交换两者的位置
-
堆取出的是最上面的数据(最小的), 最后的数据移动到最顶端, 然后再次排序
- 优先队列:自由添加数据, 取出数据要从最小值开始按顺序取出
- 堆的树形结构中, 每个顶点成为 结点 node
- 每个结点最多两个子结点. 排列从上到下, 从左到右
取出O(1) 重构树O(logₙ) 添加树O(logₙ)
应用场景:狄克斯特拉算法
1.8 二叉查找树
- 图的树形结构 广度优先搜索
- 每个结点的值均大于其左子树上任意一个结点的值
- 每个结点的值均小于其右子树上任意一个结点的值
- 删除的结点没有子结点, 直接删掉该结点
- 删除的结点只有一个子结点, 那么先删掉目标结点, 然后把子结点移到被删除结点的位置上
- 如果需要删除的结点有两个子结点, 那么先删掉目标结点, 然后在被删除结点的左子树中寻找最大结点
二叉查找树当作是二分查找算法思想的树形结构体现
树形状较为均衡 O(logₙ) 树形状朝单侧纵向延伸 O(n)
把子结点数扩展为 m(m 为预先设定好的常数)。像这种子结点数可以自由设定,并且形状均衡的树便是 B 树
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本