拓扑排序

拓扑排序

"""
拓扑排序:
对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是
将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),
则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。
简单的说,由某个集合上的一个偏序得到该集合上的一个全序,这个操作称之为拓扑排序。
在图论中,由一个有向无环图的顶点组成的序列,当且仅当满足下列条件时,称为该图的一个拓扑排序(英语:Topological sorting):
每个顶点出现且只出现一次;若A在序列中排在B的前面,则在图中不存在从B到A的路径。

1.在有向图中选一个没有前驱的顶点并且输出
2.从图中删除该顶点和所有以它为尾的弧(白话就是:删除所有和它有关的边)
3.重复上述两步,直至所有顶点输出,或者当前图中不存在无前驱的顶点为止,后者代表我们的有向图是有环的,
    因此,也可以通过拓扑排序来判断一个图是否有环。

1.从 DAG 图中选择一个 没有前驱(即入度为0)的顶点并输出。
2.从图中删除该顶点和所有以它为起点的有向边。
3.重复 1 和 2 直到当前的 DAG 图为空或当前图中不存在无前驱的顶点为止。若当前图中不存在无前驱的顶点说明有向图中必存在环。
"""
# 使用字典存储图和每一个顶点的入度
# graph = ['a':'bc']    k为顶点,v为以a为尾的相关的顶点
# in_degree = ['b':1]   k为顶点,v为该顶点的入度


def topoSort(graph):    # 输入一个有向无环图
    # 将每一个顶点的入度初始化为0
    in_degree = dict((v,0) for v in graph)
    l = len(in_degree)
    # 遍历图中的每一个顶点,计算每一个顶点的入度
    for i in graph:
        # 通过顶点计算与其相关的顶点的入度
        for v in graph[i]:
            in_degree[v] += 1

    s = []  # 存放入度为0的顶点
    result = []     # 存放移除的点的顺序

    # 筛选入度为0的顶点
    for i in graph:
        if in_degree[i] == 0:
            s.append(i)

    # 将入度为0的顶点移除,并且删除与其相关的边,重新筛选入度为0的顶点
    while s:
        v = s.pop()     # 移除一个入度为0的顶点
        result.append(v)
        for e in graph[v]:
            in_degree[e] -= 1   # 相关的顶点入度-1
            if in_degree[e] == 0:   # 若存在入度为0的顶点,筛选出来
                s.append(e)

    if len(result) == l:    # 若全部的顶点都移除了
        return result
    else:
        return None

if __name__ == '__main__':
    g = {
        'a':'bf',
        'b':'cdf',
        'c':'d',
        'd':'ef',
        'e':'f',
        'f':''
    }

    print(topoSort(g))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值