python数据结构与算法——图的广度优先和深度优先的算法

根据维基百科的伪代码实现:

广度优先BFS:

使用队列集合

标记初始结点已被发现,放入队列

每次循环从队列弹出一个结点

将该节点的所有相连结点放入队列,并标记已被发现

通过队列,将迷宫路口所有的门打开,从一个门进去继续打开里面的门,然后返回前一个门处

 1 """
 2  procedure BFS(G,v) is
 3      let Q be a queue
 4      Q.enqueue(v)
 5      label v as discovered
 6      while Q is not empty
 7         v ← Q.dequeue()
 8         procedure(v)
 9         for all edges from v to w in G.adjacentEdges(v) do
10             if w is not labeled as discovered
11                 Q.enqueue(w)
12                 label w as discovered
13 """
14 def procedure(v):
15     pass
16
17 def BFS(G,v0):
18     """ 广度优先搜索 """
19     q, s = [], set()
20     q.extend(v0)
21     s.add(v0)
22     while q:    # 当队列q非空
23         v = q.pop(0)
24         procedure(v)
25         for w in G[v]:     # 对图G中顶点v的所有邻近点w
26             if w not in s: # 如果顶点 w 没被发现
27                 q.extend(w)
28                 s.add(w)    # 记录w已被发现

深度优先DFS

使用 集合

初始结点入栈

每轮循环从栈中弹出一个结点,并标记已被发现

对每个弹出的结点,将其连接的所有结点放到队列中

通过栈的结构,一步步深入挖掘

 1 """"
 2 Pseudocode[edit]
 3 Input: A graph G and a vertex v of G
 4
 5 Output: All vertices reachable from v labeled as discovered
 6
 7 A recursive implementation of DFS:[5]
 8
 9 1  procedure DFS(G,v):
10 2      label v as discovered
11 3      for all edges from v to w in G.adjacentEdges(v) do
12 4          if vertex w is not labeled as discovered then
13 5              recursively call DFS(G,w)
14 A non-recursive implementation of DFS:[6]
15
16 1  procedure DFS-iterative(G,v):
17 2      let S be a stack
18 3      S.push(v)
19 4      while S is not empty
20 5            v = S.pop()
21 6            if v is not labeled as discovered:
22 7                label v as discovered
23 8                for all edges from v to w in G.adjacentEdges(v) do
24 9                    S.push(w)
25 """
26
27 def DFS(G,v0):
28     S = []
29     S.append(v0)
30     label = set()
31     while S:
32         v = S.pop()
33         if v not in label:
34             label.add(v)
35             procedure(v)
36             for w in G[v]:
37                 S.append(w)
时间: 2024-10-28 00:15:38

python数据结构与算法——图的广度优先和深度优先的算法的相关文章

图基本算法 图搜索(广度优先、深度优先)

(边自学边写,还真有点累啊,) 注:以下代码均为部分,关于图的表示方法参看我的博客: http://www.cnblogs.com/dzkang2011/p/graph_1.html 一.广度优先搜索 广度优先搜索(BFS)是最简单的图搜索算法之一,也是很多重要的图算法的原型.在Prim最小生成树算法和Dijkstra单源最短路径算法中,都采用了与广度优先搜索类似的思想. 在给定图G=(V,E)和一个特定的源顶点s的情况下,广度优先搜索系统地探索G中的边,以期发现可以从s到达的所有顶点,并计算s

算法-图的路径查询-深度优先遍历

#include <cassert> #include <vector> template<typename Graph> class Path { private: Graph &G; int s; //某一个点 bool* visited; int* from;//路径 void dfs(int v){ visited[v] = true; typename Graph::adjIterator adj(G,v); for(int i =adj.begin(

java 数据结构 图中使用的一些常用算法 图的存储结构 邻接矩阵:图的邻接矩阵存储方式是用两个数组来标示图。一个一位数组存储图顶点的信息,一个二维数组(称为邻接矩阵)存储图中边或者弧的信息。 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 实例如下,左图是一个无向图。右图是邻接矩阵表示:

以下内容主要来自大话数据结构之中,部分内容参考互联网中其他前辈的博客. 图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通过表示为G(V,E),其中,G标示一个图,V是图G中顶点的集合,E是图G中边的集合. 无边图:若顶点Vi到Vj之间的边没有方向,则称这条边为无项边(Edge),用序偶对(Vi,Vj)标示. 对于下图无向图G1来说,G1=(V1, {E1}),其中顶点集合V1={A,B,C,D}:边集合E1={(A,B),(B,C),(C,D),(D,A),(A,C)}: 有向图:若

python数据结构与算法 38 分析树

分析树 树的结构完成以后,该是时候看看它能做点什么实事儿了.这一节里,我们研究一下分析树.分析树能够用于真实世界的结构表示,象语法或数学表达式一类的. 图1 一个简单语句的分析树 图1所示是一个简单语句的层级结构,把语句表示为树结构可以让我们用子树来分析句子的组成部分. 图2 ((7+3)?(5?2))的分析树 我们也可以把数学表达式如((7+3)?(5?2))表示为分析树,如图2.此前我们研究过完全括号表达式,这个表达式表达了什么呢?我们知道乘法的优先级比加减要高,但因为括号的关系,在做乘法之

python数据结构与算法 36 树的基本概念

树 学习目标 理解什么是树及使用方法 学会使用树实现映射 用列表实现树 用类和引用实现树 用递归实现树 用堆实现优先队列 树的例子 前面我们学习过栈和队列这类线性数据结构,并且体验过递归,现在我们学习另一种通用数据结构,叫做树.树在计算机科学中应用广泛,象操作系统.图形学.数据库系统.网络等都要用到树.树和他们在自然界中的表哥--植物树--非常相似,树也有根,有分枝,有叶子.不同之处是,数据结构的树,根在顶上,而叶子在底部. 在开始学习之前,我们来研究几个普通的例子.第一个是生物学上的分级树.图

python数据结构与算法 37 树的实现

树的实现 记住上一节树的定义,在定义的基础上,我们用以下的函数创建并操作二叉树: BinaryTree() 创建一个二叉树实例 getLeftChild() 返回节点的左孩子 getRightChild() 返回节点的右孩子 setRootVal(val) 把val变量值赋给当前节点 getRootVal() 返回当前节点对象. insertLeft(val) 创建一个新二叉树作为当前节点的左孩子 insertRight(val) 创建一个新二叉树作为当前节点的右孩子. 实现树的关键点是合适的存

python数据结构与算法 34 归并排序

归并排序 在提高排序算法性能的方法中,有一类叫做分而治之.我们先研究其中第一种叫做归并排序.归并排序使用递归的方法,不停地把列表一分为二.如果列表是空或只有一个元素,那么就是排好序的(递归基点),如果列表有超过1个的元素,那么切分列表并对两个子列表递归使用归并排序.一旦这两个列表排序完成,称为"归并"的基本操作开始执行.归并是把两个有序列表合并成一个新的有序列表的过程.图10是我们熟悉的列表样例分解过程,图11是归并的过程. 图10  切分过程 图11  归并过程 以下是mergeSo

python数据结构与算法 35 快速排序

快速排序 快速排序也使用了分而治之的策略来提高性能,而且不需要额外的内存,但是这么做的代价就是,列表不是对半切分的,因而,性能上就有所下降. 快速排序选择一个数值,一般称为"轴点",虽然有很多选取轴点的方法,我们还是简单地把列表中第一个元素做为轴点了.轴点的作用是帮助把列表分为两个部分.列表完成后,轴点所在的位置叫做"切分点",从这一点上把列表分成两部分供后续调用. 图12所示,54将作为轴点.这个例子我们已经排过多次了,我们知道54在排好序后将处于现在31的位置上

python数据结构与算法 39 树的遍历

树的遍历 在学习完成树的基本结构以后,我们开始研究一些树的应用模式.访问树的全部节点,一般有三种模式,这些模式的不同之处,仅在于访问节点的顺序不同.我们把这种对节点的访问称为"遍历",这三种遍历模式叫做前序.中序和后序.下面我们对遍历模式作更仔细的定义,同时研究使用这延续模式的例子. 前序遍历 在前序遍历中,先访问根节点,然后用递归方式前序遍历它的左子树,最后递归方式前序遍历右子树. 中序遍历 在中序遍历中,先递归中序遍历左子树,然后访问根节点,最后递归中序遍历右子树. 后序遍历 在后