- [X] 👀️ 图在Python中的表示方法有哪些?
- [X] 🎉️ DFS
- [X] BFS
- [X] Priority Queue by heap
- [ ] Dijkstra
灵魂发问
要实现图相关的算法涉及到一个问题:图这种数据结构在Python中怎么表示?—-> Task1: 弄清python中图的相关表示
图在Python中的表示方法
邻接矩阵
这个应该蛮简单的
邻接链表
Python没有指针,那么邻接链表怎么表示出来呢,看样子这部分是重点
解决方案:
参考这篇:常见的图结构表示(python)
还有这个:Python数据结构与算法视频教程
深度优先搜索(DFS)
Intuitive —— 走迷宫
Tremaux 搜索 (迷宫-图, 通道-边, 路口-顶点)
- 选择一条未标记过的通道,在走过的路上铺一条绳子
- 标记所有第一次路过的路口和通道
- 当来到一个标记过的路口时回退到上个路口
- 当回退到的路口已没有可走的通道时继续回退
划重点:
绳子
,标记
动手实现
Version1——递归
和Tremaux类似,访问其中一个顶点时:
- 标记它为已访问
- 递归(
绳子
)地访问它所有未标记过的邻结点Note: 若图是连通的,则每个顶点都会被访问到
1 | #递归 |
Version2 —— 辅助栈
注意每一次只入栈一个未标记的邻结点,最后一个未标记的邻结点都找不到了才出栈访问
1 | #辅助栈 |
测试
- 测试用例
1 | G = { |
算法遍历边和访问顶点的顺序与图的表示是有关的,而不是仅与图的结构或算法有关
测试结果
[X] 入栈时访问/出栈时访问
- [X] 递归
- [X] 显式栈
应用刷题
在应用的时候并非按部就班的套以上实现代码,重点在于算法思想的应用
这是区别于并查集的地方,原因在于并查集算是一种数据结构,而这个是实打实的算法
- [X] 200
1 | class Solution: |
- [X] 111
1 | class Solution: |
广度优先搜索 (BFS)
启发问题:单点最短路径 DFS无所作为,BFS应运而生
一组人一起朝各个方向走迷宫,每个人都有自己的绳子。出现新岔路时,一个探索者分裂为更多的人来探索;两个探索者相遇时合体,继续使用先到达者的绳子
动手实现
辅助队列 (FIFO)
1 | # %% |
测试
- 测试用例同DFS
测试结果
[X] 一种访问方式
应用刷题
- [X] 111
1 | # Definition for a binary tree node. |
- [X] 752
1 | def children(s): |
优化思路: 双向BFS (前提:知道终点在哪)
1 | def children(s): |
DFS-线-Solo-递归好写
BFS-面-团战-找最短路径适用
暂时到这儿了,有空再更新👀️
优先队列 Prior Queue
一种抽象数据类型,实现删除最小元素
(删除最大元素
可通过相应转化改写得到)和 插入元素
API (堆实现 (Heap))
1 | #API |
最大堆(大顶堆) for MaxPQ; 最小堆(小顶堆)for MinPQ
- 优先队列由一个基于堆的完全二叉树表示,存储于数组pq[1:N]中, pq[0]没有使用
- 在Insert中,我们将N加一并把新元素添加在数组最后,然后用swim()恢复堆的秩序
- 在delMin()中,我们从pq[1]得到需要返回的元素,然后将pq[N]移动到pq[1],将N减1并用sink()恢复堆的秩序
- 对于一个含有N个元素的基于堆的优先队列,插入元素操作只需不超过$(lgN+1)$次比较,删除最小元素的操作需要不超过$ 2lgN$次比较
具体实现
1 | class MinPQ: |
测试用例
1 | PQ = MinPQ() |
测试结果符合
应用刷题
- [X] 剑指Offer41
1 | ## 改写MinPQ --> MaxPQ |
1 | #构造一个大顶堆,一个小顶堆,中位数在最后的maxi和mini中求得 |
- [X] 1046
1 | ## 实例化MaxPQ |
- [X] 778
1 | #改写三元组版本MinPQ ----> 实质BFS with MinPQ (3-ele-tuple-version) |
Python Standard Library —— heapq
- MinPQ
- zero-based Indexing
- pop method returns the smallest item
- heap[0] is the smallest item, and heap.sort() maintains the heap invariant
1 | #Push the value item onto the heap, maintaining the heap invariant. |
The module also offers three general purpose functions based on heaps:
- heapq.merge(*iterables, key=None, reverse=False)
- heapq.nlargest(n, iterable, key=None)
- heapq.nsmallest(n, iterable, key=None)
See Souce Code: cpython/Lib/heapq.py
- [X] 778 by using heapq
1 | class Solution: |
Dijkstra
- Like BFS
Prior Queue
(useheap
)- Greedy
- Only consider distance from source
- Non-negative weight on edges
动手实现
应用刷题
A* Algorithm
- Also consider distance to end (approximate value, e.g. Euclidian Dist)
- Bias-version BFS
动手实现
应用刷题
Reference
《算法4》