Python中BFS必须用collections.deque,因其popleft()和append()均为O(1),而list.pop(0)是O(n),节点超2000时性能差距可达5倍以上;需用set存visited、parent字典记录路径、邻接表存图,并在入队前检查是否已访问。

Python图的BFS怎么写_广度优先搜索与队列路径查找

Python里用collections.deque写BFS最稳

不用list.pop(0)模拟队列,它每次删头是O(n)操作,图稍大就卡住。真BFS必须用deque——内部是双向链表,popleft()append()都是O(1)。

常见错误现象:list当队列跑稀疏图不明显,但节点超2000个后,耗时可能差5倍以上;更隐蔽的是,某些测试用例会故意加长路径,让list.pop(0)退化成纯暴力遍历。

路径还原得靠parent字典,不是靠队列顺序

BFS本身只保证第一次到达某节点的距离最短,但队列里不存路径信息。想返回具体路径,必须在访问邻居时记录“谁带它来的”。

使用场景:找最短路径字符串、输出节点序列、做导航类逻辑。如果只要判断连通性或最短距离,parent可省略。

graph用邻接表还是邻接矩阵?看数据规模和稀疏度

邻接矩阵(二维listnumpy数组)查边快O(1),但建表O(n²),内存吃紧;邻接表(dictlistset)省内存、遍历快,适合绝大多数图问题。

性能影响:1000节点以下两者差别不大;上万节点且边数不到节点平方的1%,邻接表快3倍以上,内存少90%。

遇到MemoryError或超时,先检查是否漏了visited判重

这是BFS最常踩的坑——没在入队前检查是否已访问,导致同一节点反复进队,队列爆炸式增长。小图可能只是慢,大图直接崩。

错误现象:len(queue)在几轮后突然飙到百万级;visited集合大小远小于预期节点数;CPU跑满但没进展。

事情说清了就结束。真正难的不是写出BFS,是每次写都下意识检查那三处:队列用没用deque、路径有没有记parentvisited有没有在正确位置拦住重复节点。
本文转载于:互联网 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。