【图】用python实现有向图的DFS

深度优先搜索(DFS)是一种有效的图遍历方法,类似于二叉树的前序/中序/后续遍历,其从初始搜索节点开始,递归的向下搜索。

# 1. 创建Vertex对象
class Vertex(object):
    """
    节点对象,在基础节点对象的基础上,添加了关于着色、前驱节点以及距离的相关属性和方法
    """
    def __init__(self, key):
        self.key = key
        self.connectedTo = {}    # 存放指向的其它节点,以Vertex:连接边weight的
        self.color = "white"   # BFS中的状态标记
        self.predecessor = None     # BFS时前驱节点的标记
        self.time = [0, 0]          # [search_time, finish_time], 分别表示开始探索该节点子图,以及结束探索该节点所在子图的时间

    def addNeighbor(self, nbr, weight):
        self.connectedTo.update({nbr: weight})

    def __str__(self):
        return str(self.key) + '-->' + str([nbr.key for nbr in self.connectedTo])

    def getConnections(self):
        return self.connectedTo.keys()

    def getId(self):
        return self.key

    def getWeight(self, nbr):
        weight = self.connectedTo.get(nbr)
        if weight is not None:
            return weight
        else:
            raise KeyError("No such nbr exist!")

    def getColor(self):
        return self.color

    def setColor(self, color):
        self.color = color

    def setPredecessor(self, vertex):
        self.predecessor = vertex

    def getPredecessor(self):
        return self.predecessor

    def setSearchTime(self, time):
        self.time[0] = time

    def setFinishTime(self, time):
        self.time[1] = time


# 2. 创建Graph对象
class Graph(object):
    """
    图对象
    """
    def __init__(self):
        self.vertexList = {}         # 字典保存节点信息,以{key: Vertex}的方式
        self.vertexNum = 0           # 统计图节点数
        self.time = 0                # DFS遍历所有节点所需的步骤

    def addVertex(self, key):
        self.vertexList.update({key: Vertex(key)})
        self.vertexNum += 1

    def getVertex(self, key):
        vertex = self.vertexList.get(key)
        return vertex

    def __contains__(self, key):
        return key in self.vertexList.values()

    def addEdge(self, f, t, weight=0):
        if not self.getVertex(f):
            self.addVertex(f)
        if not self.getVertex(t):
            self.addVertex(t)
        self.vertexList[f].addNeighbor(self.vertexList[t], weight=weight)

    def getVertices(self):
        return self.vertexList.keys()

    def __iter__(self):
        return iter(self.vertexList.values())

    def dfs(self):
        for startVertex in self:   # type: Vertex
            if startVertex.getColor() == 'white':
                self._dfs(startVertex)               # 以所有节点为子图起始点进行遍历,防止有非联通子图

    def _dfs(self, startVertex: Vertex):
        startVertex.setColor('gray')
        self.time += 1
        startVertex.setSearchTime(self.time)
        for aVertex in startVertex.getConnections():    # type: Vertex
            if aVertex.getColor() == 'white':
                aVertex.setPredecessor(startVertex)
                self._dfs(aVertex)
        startVertex.setColor('black')
        self.time += 1
        startVertex.setFinishTime(self.time)


if __name__ == '__main__':
    g = Graph()
    g.addEdge('A', 'B')
    g.addEdge('B', 'C')
    g.addEdge('A', 'D')
    g.addEdge('B', 'D')
    g.addEdge('D', 'E')
    g.addEdge('E', 'F')
    g.addEdge('E', 'B')
    g.addEdge('F', 'C')
    g.dfs()
    print(g.time)
    print(g.getVertex('B').time)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值