拓扑排序及实现


title: 拓扑排序及实现
date: 2019-09-03 19:45:00
tags: python,数据结构
categories: 计算机理论

拓扑排序

算法原理

拓扑排序是有向图(网)中的内容,只在有向网(图)的范畴中讨论。

先看一个实际生活中可能遇到的问题:选课问题,例如上大一的时候你肯定要先学C语言,然后才能学数据结构。这个时候C语言和数据结构就构成了一个排列问题,谁在前谁在后。用图中的顶点表示一个活动,边表示活动之间的顺序关系。这样的图就称为AOV网(顶点活动网)

下图就是一个典型的AOV网实例。

20190831210501

任何无回路的AOV网N都可以求解出拓扑序列,方法很简单:

  • 从N中选出一个入度为0的顶点作为序列的下一个顶点
  • 从N网中删除所选顶点的出边
  • 重复执行上面两步,直到已经选出了图N的所有顶点

拓扑排序算法有两个难点:

  1. 如何寻找入度为0的顶点
  2. 真的需要拷贝整张图,然后进行删除

一个显然的办法是不断遍历图,寻找入度为0的顶点。但时间代价会很高。顶点间的制约关系决定了顶点的入度。入度是一个整数,用一个整数表就能记录所以顶点的入度了。因此,我的方法是用一张入度表记录了每个顶点的入度,初始时,表中的各顶点的入度对应为图中顶点的入度,在随后的计算中,一旦选中一个顶点,就将该顶点的出边入度减一。

在实际的算法实现中还用了一个0度栈来记录已经入度为0但还未处理的顶点。

算法比较简单。

可以慢慢调试

20190831212236

算法实现

    def topological_sort(self):
        indegree = {}  # 入度表
        zerov = []  # 利用0度栈记录已知的入度为0的但还未处理的顶点
        m = 0  # 输出顶点计数
        topo = []  # 拓扑排序结果
        # 生成入度表和0度栈
        for vetx in self._graph:
            indegree[vetx] = self.get_inEdge(vetx).__len__()
            if indegree[vetx] == 0:
                zerov.append(vetx)
            pass

        while zerov.__len__() != 0:
            Vi = zerov.pop()
            topo.append(Vi)
            m += 1
            for Vj in self.get_outEdge(Vi).keys():  # 对顶点Vi的每个邻接点入度减1,如果Vj的入度变为0,则将Vj入栈,表示Vj就是下一个需要处理的顶点
                indegree[Vj] -= 1
                if indegree[Vj] == 0:
                    zerov.append(Vj)

        if m < self.get_vertexNum():  # 该有向图有回路
            return False
        return topo

测试

1567257835949

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值