数据结构与算法学习笔记-图的遍历

图的遍历

图的遍历算法有深度优先搜索算法广度优先搜索算法

深度优先搜索算法

深度优先搜索属于图算法的一种,是一个针对图和树的遍历算法,英文缩写为DFS(Depth First Search)。深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图论问题,如最大路径问题等等。一般用堆数据结构来辅助实现DFS算法。其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。

采用的数据结构是(正)邻接链表。

深度优先搜素遍历类似树的先序遍历,是树的先序遍历的推广。

算法思想:

设初始状态时图中的所有顶点未被访问,则:

(1):从图中某个定点Vi出发,访问Vi;然后找到Vi的一个邻接顶点Vi1;

(2):从Vi1出发,深度优先搜索访问和Vi1相邻接且未被访问的所有顶点;

(3):转(1),直到和Vi相邻接的所有顶点都被访问为止;

(4):继续选取图中未被访问顶点Vj作为起始顶点,转(1),直到图中所有顶点都被访问为止

如下图所示:
数据结构与算法学习笔记-图的遍历_第1张图片

算法代码:

#!/usr/bin/python
# -*- coding: utf-8 -*-

class Graph(object):

    def __init__(self,*args,**kwargs):
        self.node_neighbors = {}
        self.visited = {}

    def add_nodes(self,nodelist):

        for node in nodelist:
            self.add_node(node)

    def add_node(self,node):
        if not node in self.nodes():
            self.node_neighbors[node] = []

    def add_edge(self,edge):
        u,v = edge
        if(v not in self.node_neighbors[u]) and ( u not in self.node_neighbors[v]):
            self.node_neighbors[u].append(v)

            if(u!=v):
                self.node_neighbors[v].append(u)

    def nodes(self):
        return self.node_neighbors.keys()
    """
    #深度优先遍历函数
    # Depth-First-Search 
        深度优先算法,是一种用于遍历或搜索树或图的算法。沿着树的深度遍历树的节点,尽可能深的搜索树的分支。
        当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。
        这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,
        则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。        
    """
    def depth_first_search(self,root=None):
        order = []
        def dfs(node):
            self.visited[node] = True
            order.append(node)
            for n in self.node_neighbors[node]:
                if not n in self.visited:
                    dfs(n)


        if root:
            dfs(root)

        for node in self.nodes():
            if not node in self.visited:
                dfs(node)

        print(order)
        return order


if __name__ == '__main__':
    g = Graph()
g.add_nodes([i+1 for i in range(9)])
g.add_edge((1, 2))
g.add_edge((1, 8))
g.add_edge((2, 3))
g.add_edge((2, 5))
g.add_edge((3, 4))
g.add_edge((4, 5))
g.add_edge((4, 6))
g.add_edge((6, 7))
g.add_edge((6, 8))
g.add_edge((8, 9))
print("nodes:", g.nodes())

order = g.depth_first_search(1)
    
#运行结果:1,2,3,4,5,6,7,8,9

广度优先搜索算法

广度优先搜索算法(Breadth First Search),又称为“宽度优先搜索”或“横向优先搜索”,简称BFS;BFS是用于图的查找算法。

BFS可用于解决2类问题:

  • 从A出发是否存在到达B的路径;
  • 从A出发到达B的最短路径(这个应该叫最少步骤合理);

算法思想:

​ 从图中某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使得“先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问,直至图中所有已被访问的顶点的邻接点都被访问到。如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为新的起始点,重复上述过程,直至图中所有顶点都被访问到为止。

如下图所示:
数据结构与算法学习笔记-图的遍历_第2张图片
算法代码:

#!/usr/bin/python
# -*- coding: utf-8 -*-

class Graph(object):

    def __init__(self,*args,**kwargs):
        self.node_neighbors = {}
        self.visited = {}

    def add_nodes(self,nodelist):

        for node in nodelist:
            self.add_node(node)

    def add_node(self,node):
        if not node in self.nodes():
            self.node_neighbors[node] = []

    def add_edge(self,edge):
        u,v = edge
        if(v not in self.node_neighbors[u]) and ( u not in self.node_neighbors[v]):
            self.node_neighbors[u].append(v)

            if(u!=v):
                self.node_neighbors[v].append(u)

    def nodes(self):
        return self.node_neighbors.keys()

    
    #广度优先遍历函数
    def breadth_first_search(self,root=None):
        queue = []
        order = []
        def bfs():
            while len(queue)> 0:
                node  = queue.pop(0)

                self.visited[node] = True
                for n in self.node_neighbors[node]:
                    if (not n in self.visited) and (not n in queue):
                        queue.append(n)
                        order.append(n)

        if root:
            queue.append(root)
            order.append(root)
            bfs()

        for node in self.nodes():
            if not node in self.visited:
                queue.append(node)
                order.append(node)
                bfs()
        print(order)

        return order
    

if __name__ == '__main__':
    g = Graph()
g.add_nodes([i+1 for i in range(9)])
g.add_edge((1, 2))
g.add_edge((1, 8))
g.add_edge((2, 3))
g.add_edge((2, 5))
g.add_edge((3, 4))
g.add_edge((4, 5))
g.add_edge((4, 6))
g.add_edge((6, 7))
g.add_edge((6, 8))
g.add_edge((8, 9))
print("nodes:", g.nodes())

order = g.breadth_first_search(1)

#运行结果:1,2,8,3,5,6,4,7

你可能感兴趣的:(学习笔记)