Breadth-first traversal BFS & depth-first traversal DFS (python code implementation)

Table of contents

breadth first traversal

Depth-first traversal

python code

 expand

weighted graph


breadth first traversal

        First traverse the nodes adjacent to the current node, then traverse the nodes one layer deeper, and proceed layer by layer until a suitable result is found.

 

ABCDEFGHIJK and ABCDEF

Features: When solving problems, in most cases, it is not necessary to traverse the entire graph.

Implementation method: queue.

Application: Find the shortest path in an unweighted graph.

Traverse steps:

1. Define an operation queue Que, an array Arr that records the scanned nodes, and an array res of the traversed results.

2. Given the start node start, enqueue the start node and add it to the array Arr.

3. Perform a scan (as long as the queue is not empty):

        Dequeue operation, and update the dequeue node v to the new starting node start.        

        Scan the nodes adjacent (connected) to the starting node start, and judge whether they have been scanned through the Arr array:

                If scanned, continue.

                If not, enqueue and join the array Arr.

        The currently dequeued node v is added to the result array res.

Depth-first traversal

        One road goes to the dark, and if it fails, go back to the previous fork until the whole map is completed.

ABDHIEJCFGK and ABDFEC

Features: When solving a problem, it is necessary to traverse the entire graph.

Implementation method: stack.

Application: How many solutions are there, how many paths are there, the maximum path and similar problems.

Traverse steps:

1. Define an operation stack stack, an array Arr that records the scanned nodes, and an array res of the traversed results.

2. Given the start node start, execute the start node into the stack and add it to the array Arr.

3. Perform a scan (as long as the stack is not empty):

        Pop out operation, and update the pop-up node v to the new starting node start.        

        Scan the nodes adjacent (connected) to the starting node start, and judge whether they have been scanned through the Arr array:

                If scanned, continue.

                If not, it is pushed onto the stack and added to the array Arr.

        The currently popped node v is added to the result array res.

Note: BFS and DFS may not have a unique path when traversing the search

Such as DFS:

 

python code

breadth first traversal

#  构造图
graph = {"A": ['B', 'C'],
         "B": ['A', 'C', 'D'],
         "C": ['A', 'B', 'D', 'E'],
         "D": ['B', 'C', 'E', 'F'],
         "E": ['C', 'D'],
         "F": ['D']}

# graph图结构,start_v起始结点
def BFS(graph, start_v):
    queue = []  # 队列
    check = set()  # 已经访问过
    queue.append(start_v)  # 放入起始结点
    check.add(start_v)  # 放入起始结点

    # 遍历访问图
    while len(queue) > 0:
        vertex = queue.pop(0)
        nodes = graph[vertex]
        # 从当前结点相连接的结点中寻找
        for v in nodes:
            # 判断是否已经访问过,没有则访问
            if v not in check:
                queue.append(v)
                check.add(v)
        print(vertex)  # 依次访问的节点


if __name__=="__main__":
    # 宽度优先遍历
    BFS(graph, 'A')

Depth-first traversal

#  构造图
graph = {"A": ['B', 'C'],
         "B": ['A', 'C', 'D'],
         "C": ['A', 'B', 'D', 'E'],
         "D": ['B', 'C', 'E', 'F'],
         "E": ['C', 'D'],
         "F": ['D']}


# graph图结构,start_v起始结点
def DFS(graph, start_v):
    stack = []  # 栈
    check = set()  # 已经访问过
    stack.append(start_v)  # 放入起始结点
    check.add(start_v)  # 放入起始结点

    # 遍历访问图
    while len(stack) > 0:
        vertex = stack.pop()
        nodes = graph[vertex]
        # 从当前结点相连接的结点中寻找
        for v in nodes:
            # 判断是否已经访问过,没有则访问
            if v not in check:
                stack.append(v)
                check.add(v)
        print(vertex)  # 依次访问的节点

if __name__=="__main__":

    # 深度优先遍历
    DFS(graph, 'A')

 expand

Save the parent node

Find the shortest distance (from the current node to the starting node)

graph = {"A": ['B', 'C'],
         "B": ['A', 'C', 'D'],
         "C": ['A', 'B', 'D', 'E'],
         "D": ['B', 'C', 'E', 'F'],
         "E": ['C', 'D'],
         "F": ['D']}

# 记录父节点,求最短路径(距离)
def BFSsuper(graph, start_v):
    queue = []  # 队列
    check = set()  # 已经访问过
    parent = {start_v: None}  # 记录父节点
    queue.append(start_v)  # 放入起始结点
    check.add(start_v)  # 放入起始结点

    # 遍历访问图
    while len(queue) > 0:
        vertex = queue.pop(0)
        nodes = graph[vertex]
        # 从当前结点相连接的结点中寻找
        for v in nodes:
            # 判断是否已经访问过,没有则访问
            if v not in check:
                queue.append(v)
                check.add(v)
                parent[v] = vertex
        #print(vertex)  # 依次访问的节点
    # 返回父结点
    return parent

if __name__=="__main__":
    # 扩展(记录父节点)
    start_v = 'A'
    parent = BFSsuper(graph, start_v)
    print('-----')
    print("结点", "父结点")
    for key in parent:
        print(key, parent[key])
    print('-----')

    # 求最短路径(距离),从一个节点到遍历的初始节点的路径,通过父节点查找,直到触顶结束
    node_start = 'E'
    print("结点{}到起始结点{}的最短路径为:" .format(node_start, start_v))
    while node_start != None:
        print(node_start, end=", ")
        node_start = parent[node_start]

weighted graph

dijkstra's algorithm

import math
import heapq

weightedGrah = {"A": {'B': 5, 'C': 1},
                "B": {'A': 5, 'C': 2, 'D': 1},
                "C": {'A': 1, 'B': 2, 'D': 4, 'E': 8},
                "D": {'B': 1, 'C': 4, 'E': 3, 'F': 6},
                "E": {'C': 8, 'D': 3},
                "F": {'D': 6}}

# 初始化距离
def init_distance(graph, stat_v):
    distance = {stat_v: 0}  # 起始点距离标为0
    # 其它点距离标为正无穷
    for vertex in graph:
        if vertex != stat_v:
            distance[vertex] = math.inf
    return distance

# 加权图,dijkstra算法,求最短路径(距离)
def dijkstra(graph, start_v):
    # 创建优先队列
    pqueue = []
    heapq.heappush(pqueue, (0, start_v))
    check = set()  # 已经访问过
    parent = {start_v: None}  # 记录父节点
    distance = init_distance(graph, start_v)  # 统计当前结点到起始结点的距离

    while len(pqueue) > 0:
        pair = heapq.heappop(pqueue)
        dist = pair[0]
        vertex = pair[1]
        check.add(vertex)

        nodes = graph[vertex].keys()
        for v in nodes:
            if v not in check:
                # 确保最短距离
                if dist+graph[vertex][v] < distance[v]:
                    heapq.heappush(pqueue, (dist+graph[vertex][v], v))
                    parent[v] = vertex
                    distance[v] = dist+graph[vertex][v]
    return parent, distance

if __name__=="__main__":
    # 加权图
    parent, distance = dijkstra(weightedGrah, 'A')
    #print(parent)
    print(distance)

Guess you like

Origin blog.csdn.net/qq_41750911/article/details/124950559