【算法】有向无环图

拓扑排序有2中方法(最后结果可能不同,因为拓扑排序有多解)。 
一个简单的求拓扑排序的 算法是先找出任意一个没有入边的顶点,然后将它和它的边从图中删除。然后对剩余部分使用同样的操作。
<code
 class="hljs cs has-numbering" style="display: block; padding: 0px; 
color: inherit; box-sizing: border-box; font-family: "Source Code Pro", 
monospace;font-size:undefined; white-space: pre; border-radius: 0px; 
word-wrap: normal; background: transparent;">    <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">public</span> ArrayList<Integer> <span 
class="hljs-title" style="box-sizing: 
border-box;">topo</span>()
    {
        ArrayList<Integer> result = <span class="hljs-keyword" 
style="color: rgb(0, 0, 136); box-sizing: 
border-box;">new</span> ArrayList<>();
        Queue<Integer> que = <span class="hljs-keyword" 
style="color: rgb(0, 0, 136); box-sizing: 
border-box;">new</span> LinkedList<>();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">int</span>[] ind = <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">new</span> <span class="hljs-keyword" 
style="color: rgb(0, 0, 136); box-sizing: 
border-box;">int</span>[V];
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">for</span>(<span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">int</span> i=<span class="hljs-number" 
style="color: rgb(0, 102, 102); box-sizing: 
border-box;">0</span>;i<V;i++)
            ind[i] = <span class="hljs-number" style="color: rgb(0, 
102, 102); box-sizing: border-box;">0</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">for</span>(LinkedList<Integer> 
nodes:adj)
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">for</span>(<span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">int</span> x:nodes)
                ind[x]++;

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">for</span>(<span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">int</span> i=<span class="hljs-number" 
style="color: rgb(0, 102, 102); box-sizing: 
border-box;">0</span>;i<V;i++)
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">if</span>(ind[i]==<span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">0</span>)
                que.offer(i);

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">while</span>(!que.isEmpty())
        {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">int</span> k = que.poll();
            result.add(k);
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">for</span>(<span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">int</span> x:adj(k))
            {
                ind[x]--;
                <span class="hljs-keyword" style="color: rgb(0, 0, 
136); box-sizing: border-box;">if</span>(ind[x]==<span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">0</span>)
                    que.offer(x);
            }
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">return</span> result;
    }</code><ul class="pre-numbering" style="box-sizing: 
border-box; position: absolute; width: 50px; top: 0px; left: 0px; 
margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 
221, 221); list-style: none; text-align: right; opacity: 0.30994; 
background-color: rgb(238, 238, 238);"><li style="box-sizing: 
border-box; padding: 0px 5px;">1</li><li style="box-sizing: 
border-box; padding: 0px 5px;">2</li><li style="box-sizing: 
border-box; padding: 0px 5px;">3</li><li style="box-sizing: 
border-box; padding: 0px 5px;">4</li><li style="box-sizing: 
border-box; padding: 0px 5px;">5</li><li style="box-sizing: 
border-box; padding: 0px 5px;">6</li><li style="box-sizing: 
border-box; padding: 0px 5px;">7</li><li style="box-sizing: 
border-box; padding: 0px 5px;">8</li><li style="box-sizing: 
border-box; padding: 0px 5px;">9</li><li style="box-sizing: 
border-box; padding: 0px 5px;">10</li><li style="box-sizing:
 border-box; padding: 0px 5px;">11</li><li 
style="box-sizing: border-box; padding: 0px 5px;">12</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">13</li><li style="box-sizing: border-box; padding: 0px
 5px;">14</li><li style="box-sizing: border-box; padding: 
0px 5px;">15</li><li style="box-sizing: border-box; padding:
 0px 5px;">16</li><li style="box-sizing: border-box; 
padding: 0px 5px;">17</li><li style="box-sizing: border-box;
 padding: 0px 5px;">18</li><li style="box-sizing: 
border-box; padding: 0px 5px;">19</li><li style="box-sizing:
 border-box; padding: 0px 5px;">20</li><li 
style="box-sizing: border-box; padding: 0px 5px;">21</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">22</li><li style="box-sizing: border-box; padding: 0px
 5px;">23</li><li style="box-sizing: border-box; padding: 
0px 5px;">24</li><li style="box-sizing: border-box; padding:
 0px 5px;">25</li><li style="box-sizing: border-box; 
padding: 0px 5px;">26</li><li style="box-sizing: border-box;
 padding: 0px 5px;">27</li><li style="box-sizing: 
border-box; padding: 0px 5px;">28</li></ul><ul 
class="pre-numbering" style="box-sizing: border-box; position: absolute;
 width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; 
border-right: 1px solid rgb(221, 221, 221); list-style: none; 
text-align: right; background-color: rgb(238, 238, 238);"><li 
style="box-sizing: border-box; padding: 0px 5px;">1</li><li 
style="box-sizing: border-box; padding: 0px 5px;">2</li><li 
style="box-sizing: border-box; padding: 0px 5px;">3</li><li 
style="box-sizing: border-box; padding: 0px 5px;">4</li><li 
style="box-sizing: border-box; padding: 0px 5px;">5</li><li 
style="box-sizing: border-box; padding: 0px 5px;">6</li><li 
style="box-sizing: border-box; padding: 0px 5px;">7</li><li 
style="box-sizing: border-box; padding: 0px 5px;">8</li><li 
style="box-sizing: border-box; padding: 0px 5px;">9</li><li 
style="box-sizing: border-box; padding: 0px 5px;">10</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">11</li><li style="box-sizing: border-box; padding: 0px
 5px;">12</li><li style="box-sizing: border-box; padding: 
0px 5px;">13</li><li style="box-sizing: border-box; padding:
 0px 5px;">14</li><li style="box-sizing: border-box; 
padding: 0px 5px;">15</li><li style="box-sizing: border-box;
 padding: 0px 5px;">16</li><li style="box-sizing: 
border-box; padding: 0px 5px;">17</li><li style="box-sizing:
 border-box; padding: 0px 5px;">18</li><li 
style="box-sizing: border-box; padding: 0px 5px;">19</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">20</li><li style="box-sizing: border-box; padding: 0px
 5px;">21</li><li style="box-sizing: border-box; padding: 
0px 5px;">22</li><li style="box-sizing: border-box; padding:
 0px 5px;">23</li><li style="box-sizing: border-box; 
padding: 0px 5px;">24</li><li style="box-sizing: border-box;
 padding: 0px 5px;">25</li><li style="box-sizing: 
border-box; padding: 0px 5px;">26</li><li style="box-sizing:
 border-box; padding: 0px 5px;">27</li><li 
style="box-sizing: border-box; padding: 0px 
5px;">28</li></ul>

定义: 拓扑排序是对有向无环图(DAG)的顶点的一种排序, 使得如果存在一条从v到w的路径,那么在排序中w就出现在v的后面。 
如果图含有环,那么拓扑排序是不可能的。试想有3个正整数,a比b大,b比c大,c比a大,我们无法对abc排序。

算法: 
1. 一个简单的求拓扑排序的算法是先找出任意一个没有入边的顶点,然后将它和它的边从图中删除。然后对剩余部分使用同样的操作。 
2. 另一种不那么直观,却更加简单的算法是求所有顶点的逆后序排列

第二种方法:

所以我们要做的就是: 
先判断该图是不是一幅有向无环图,如果是,则进行拓扑排序。在这个过程中,我们需要用dfs遍历该图2遍

性能分析: 
使用深度优先搜索对有向无环图进行拓扑排序所需的时间和V+E成正比。


检测有向图中是否有环:

用深度优先搜索来解决这个问题并不困难,一旦我们找到了一条有向边v->w且w已经存在于栈中,就找到了一个环。

实现中使用了一个onStack[]数组,以标记递归调用的栈上的所有顶点。而路径信息依然可以通过from[]数组得到。

下例是个简单实现,只能保存遍历过程中检测到的最后一条环路。但已经足够了,代码修改起来也十分简单。

<code
 class="hljs java has-numbering" style="display: block; padding: 0px; 
color: inherit; box-sizing: border-box; font-family: "Source Code Pro", 
monospace;font-size:undefined; white-space: pre; border-radius: 0px; 
word-wrap: normal; background: transparent;"><span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">package</span> DiGraphs;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">import</span> java.util.Stack;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">public</span> <span class="hljs-class" 
style="box-sizing: border-box;"><span class="hljs-keyword" 
style="color: rgb(0, 0, 136); box-sizing: 
border-box;">class</span> <span class="hljs-title" 
style="box-sizing: border-box; color: rgb(102, 0, 
102);">CycleDetect</span> {</span>

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">private</span> DiGraph g;<span 
class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: 
border-box;">//有向图</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">private</span> <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">boolean</span>[] marked;<span 
class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: 
border-box;">//是否被访问过</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">private</span> Stack<Integer> 
cycle;<span class="hljs-comment" style="color: rgb(136, 0, 0); 
box-sizing: border-box;">//存放有向环路径的栈</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">private</span> <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">boolean</span>[] onStack;<span 
class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: 
border-box;">//判断索引位置的顶点是否在栈中</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">private</span> <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">int</span> from[];<span class="hljs-comment" 
style="color: rgb(136, 0, 0); box-sizing: 
border-box;">//保存路径信息</span>


    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">public</span> <span 
class="hljs-title" style="box-sizing: 
border-box;">CycleDetect</span>(DiGraph g) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">this</span>.g = g;
        marked = <span class="hljs-keyword" style="color: rgb(0, 0, 
136); box-sizing: border-box;">new</span> <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">boolean</span>[g.V()];
        onStack = <span class="hljs-keyword" style="color: rgb(0, 0, 
136); box-sizing: border-box;">new</span> <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">boolean</span>[g.V()];
        from = <span class="hljs-keyword" style="color: rgb(0, 0, 
136); box-sizing: border-box;">new</span> <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">int</span>[g.V()];
    }

    <span class="hljs-javadoc" style="color: rgb(136, 0, 0); 
box-sizing: border-box;">/**
     * 遍历有向图,对所有连同分量都进行深度优先搜索
     */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">public</span> <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">void</span> <span class="hljs-title" 
style="box-sizing: border-box;">dfs</span>(){
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">for</span> (<span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">int</span> v = <span class="hljs-number" 
style="color: rgb(0, 102, 102); box-sizing: 
border-box;">0</span>; v < g.V(); v++)
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">if</span> (!marked(v))
                dfs(g, v);
    }

    <span class="hljs-javadoc" style="color: rgb(136, 0, 0); 
box-sizing: border-box;">/**
     * 深度优先搜索,将路径信息保存在from数组。如果发现有环,则将路径放入cycle栈中。
     *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); 
box-sizing: border-box;"> @param</span> g
     *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); 
box-sizing: border-box;"> @param</span> s
     */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">private</span> <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">void</span> <span class="hljs-title" 
style="box-sizing: border-box;">dfs</span>(DiGraph g, <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">int</span> s) {
        marked[s] = <span class="hljs-keyword" style="color: rgb(0, 
0, 136); box-sizing: border-box;">true</span>;
        onStack[s] = <span class="hljs-keyword" style="color: rgb(0, 
0, 136); box-sizing: border-box;">true</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">for</span> (<span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">int</span> w : g.adj(s))
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">if</span> (<span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">this</span>.hasCycle())
                <span class="hljs-keyword" style="color: rgb(0, 0, 
136); box-sizing: border-box;">return</span>;
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">else</span> <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">if</span> (!marked(w)) {
                from[w] = s;
                dfs(g, w);
            } <span class="hljs-keyword" style="color: rgb(0, 0, 
136); box-sizing: border-box;">else</span> <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">if</span> (onStack[w]) {<span 
class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: 
border-box;">//如果已被访问且在栈内</span>
                cycle = <span class="hljs-keyword" style="color: 
rgb(0, 0, 136); box-sizing: border-box;">new</span> 
Stack<Integer>();
                <span class="hljs-keyword" style="color: rgb(0, 0, 
136); box-sizing: border-box;">for</span> (<span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">int</span> x = s; x != w; x = from[x])
                    cycle.push(x);<span class="hljs-comment" 
style="color: rgb(136, 0, 0); box-sizing: 
border-box;">//将路径逆序push进栈中</span>
                cycle.push(w);
                cycle.push(s);
            }
        onStack[s] = <span class="hljs-keyword" style="color: rgb(0, 
0, 136); box-sizing: border-box;">false</span>;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">public</span> <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">boolean</span> <span class="hljs-title" 
style="box-sizing: border-box;">hasCycle</span>() {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">return</span> cycle != <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">null</span>;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">public</span> Iterable<Integer> 
<span class="hljs-title" style="box-sizing: 
border-box;">cycle</span>(){
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">return</span> cycle;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">private</span> <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">boolean</span> <span class="hljs-title" 
style="box-sizing: border-box;">marked</span>(<span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">int</span> w) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">return</span> marked[w];
    }



    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">public</span> <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">static</span> <span class="hljs-keyword" 
style="color: rgb(0, 0, 136); box-sizing: 
border-box;">void</span> <span class="hljs-title" 
style="box-sizing: border-box;">main</span>(String[] args) {
        DiGraph g = <span class="hljs-keyword" style="color: rgb(0, 
0, 136); box-sizing: border-box;">new</span> DiGraph(<span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">13</span>);
        g.addEdge(<span class="hljs-number" style="color: rgb(0, 102,
 102); box-sizing: border-box;">0</span>, <span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">5</span>);
        g.addEdge(<span class="hljs-number" style="color: rgb(0, 102,
 102); box-sizing: border-box;">5</span>, <span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">4</span>);
        g.addEdge(<span class="hljs-number" style="color: rgb(0, 102,
 102); box-sizing: border-box;">4</span>, <span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">3</span>);
        g.addEdge(<span class="hljs-number" style="color: rgb(0, 102,
 102); box-sizing: border-box;">3</span>, <span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">5</span>);
        g.addEdge(<span class="hljs-number" style="color: rgb(0, 102,
 102); box-sizing: border-box;">5</span>, <span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">0</span>);

        CycleDetect detectCycle = <span class="hljs-keyword" 
style="color: rgb(0, 0, 136); box-sizing: 
border-box;">new</span> CycleDetect(g);
        detectCycle.dfs();

        Stack<Integer> st = (Stack<Integer>) 
detectCycle.cycle();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">while</span>(!st.isEmpty()){
            System.out.print(st.pop() + <span class="hljs-string" 
style="color: rgb(0, 136, 0); box-sizing: border-box;">" 
"</span>);
        }
    }
    <span class="hljs-comment" style="color: rgb(136, 0, 0); 
box-sizing: border-box;">//result: 3 5 4 3 </span>
}
</code><ul class="pre-numbering" style="box-sizing: border-box;
 position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; 
padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); 
list-style: none; text-align: right; opacity: 0.30994; background-color:
 rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 
0px 5px;">1</li><li style="box-sizing: border-box; padding: 
0px 5px;">2</li><li style="box-sizing: border-box; padding: 
0px 5px;">3</li><li style="box-sizing: border-box; padding: 
0px 5px;">4</li><li style="box-sizing: border-box; padding: 
0px 5px;">5</li><li style="box-sizing: border-box; padding: 
0px 5px;">6</li><li style="box-sizing: border-box; padding: 
0px 5px;">7</li><li style="box-sizing: border-box; padding: 
0px 5px;">8</li><li style="box-sizing: border-box; padding: 
0px 5px;">9</li><li style="box-sizing: border-box; padding: 
0px 5px;">10</li><li style="box-sizing: border-box; padding:
 0px 5px;">11</li><li style="box-sizing: border-box; 
padding: 0px 5px;">12</li><li style="box-sizing: border-box;
 padding: 0px 5px;">13</li><li style="box-sizing: 
border-box; padding: 0px 5px;">14</li><li style="box-sizing:
 border-box; padding: 0px 5px;">15</li><li 
style="box-sizing: border-box; padding: 0px 5px;">16</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">17</li><li style="box-sizing: border-box; padding: 0px
 5px;">18</li><li style="box-sizing: border-box; padding: 
0px 5px;">19</li><li style="box-sizing: border-box; padding:
 0px 5px;">20</li><li style="box-sizing: border-box; 
padding: 0px 5px;">21</li><li style="box-sizing: border-box;
 padding: 0px 5px;">22</li><li style="box-sizing: 
border-box; padding: 0px 5px;">23</li><li style="box-sizing:
 border-box; padding: 0px 5px;">24</li><li 
style="box-sizing: border-box; padding: 0px 5px;">25</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">26</li><li style="box-sizing: border-box; padding: 0px
 5px;">27</li><li style="box-sizing: border-box; padding: 
0px 5px;">28</li><li style="box-sizing: border-box; padding:
 0px 5px;">29</li><li style="box-sizing: border-box; 
padding: 0px 5px;">30</li><li style="box-sizing: border-box;
 padding: 0px 5px;">31</li><li style="box-sizing: 
border-box; padding: 0px 5px;">32</li><li style="box-sizing:
 border-box; padding: 0px 5px;">33</li><li 
style="box-sizing: border-box; padding: 0px 5px;">34</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">35</li><li style="box-sizing: border-box; padding: 0px
 5px;">36</li><li style="box-sizing: border-box; padding: 
0px 5px;">37</li><li style="box-sizing: border-box; padding:
 0px 5px;">38</li><li style="box-sizing: border-box; 
padding: 0px 5px;">39</li><li style="box-sizing: border-box;
 padding: 0px 5px;">40</li><li style="box-sizing: 
border-box; padding: 0px 5px;">41</li><li style="box-sizing:
 border-box; padding: 0px 5px;">42</li><li 
style="box-sizing: border-box; padding: 0px 5px;">43</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">44</li><li style="box-sizing: border-box; padding: 0px
 5px;">45</li><li style="box-sizing: border-box; padding: 
0px 5px;">46</li><li style="box-sizing: border-box; padding:
 0px 5px;">47</li><li style="box-sizing: border-box; 
padding: 0px 5px;">48</li><li style="box-sizing: border-box;
 padding: 0px 5px;">49</li><li style="box-sizing: 
border-box; padding: 0px 5px;">50</li><li style="box-sizing:
 border-box; padding: 0px 5px;">51</li><li 
style="box-sizing: border-box; padding: 0px 5px;">52</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">53</li><li style="box-sizing: border-box; padding: 0px
 5px;">54</li><li style="box-sizing: border-box; padding: 
0px 5px;">55</li><li style="box-sizing: border-box; padding:
 0px 5px;">56</li><li style="box-sizing: border-box; 
padding: 0px 5px;">57</li><li style="box-sizing: border-box;
 padding: 0px 5px;">58</li><li style="box-sizing: 
border-box; padding: 0px 5px;">59</li><li style="box-sizing:
 border-box; padding: 0px 5px;">60</li><li 
style="box-sizing: border-box; padding: 0px 5px;">61</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">62</li><li style="box-sizing: border-box; padding: 0px
 5px;">63</li><li style="box-sizing: border-box; padding: 
0px 5px;">64</li><li style="box-sizing: border-box; padding:
 0px 5px;">65</li><li style="box-sizing: border-box; 
padding: 0px 5px;">66</li><li style="box-sizing: border-box;
 padding: 0px 5px;">67</li><li style="box-sizing: 
border-box; padding: 0px 5px;">68</li><li style="box-sizing:
 border-box; padding: 0px 5px;">69</li><li 
style="box-sizing: border-box; padding: 0px 5px;">70</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">71</li><li style="box-sizing: border-box; padding: 0px
 5px;">72</li><li style="box-sizing: border-box; padding: 
0px 5px;">73</li><li style="box-sizing: border-box; padding:
 0px 5px;">74</li><li style="box-sizing: border-box; 
padding: 0px 5px;">75</li><li style="box-sizing: border-box;
 padding: 0px 5px;">76</li><li style="box-sizing: 
border-box; padding: 0px 5px;">77</li><li style="box-sizing:
 border-box; padding: 0px 5px;">78</li><li 
style="box-sizing: border-box; padding: 0px 5px;">79</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">80</li><li style="box-sizing: border-box; padding: 0px
 5px;">81</li><li style="box-sizing: border-box; padding: 
0px 5px;">82</li><li style="box-sizing: border-box; padding:
 0px 5px;">83</li><li style="box-sizing: border-box; 
padding: 0px 5px;">84</li><li style="box-sizing: border-box;
 padding: 0px 5px;">85</li><li style="box-sizing: 
border-box; padding: 0px 5px;">86</li></ul><ul 
class="pre-numbering" style="box-sizing: border-box; position: absolute;
 width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; 
border-right: 1px solid rgb(221, 221, 221); list-style: none; 
text-align: right; background-color: rgb(238, 238, 238);"><li 
style="box-sizing: border-box; padding: 0px 5px;">1</li><li 
style="box-sizing: border-box; padding: 0px 5px;">2</li><li 
style="box-sizing: border-box; padding: 0px 5px;">3</li><li 
style="box-sizing: border-box; padding: 0px 5px;">4</li><li 
style="box-sizing: border-box; padding: 0px 5px;">5</li><li 
style="box-sizing: border-box; padding: 0px 5px;">6</li><li 
style="box-sizing: border-box; padding: 0px 5px;">7</li><li 
style="box-sizing: border-box; padding: 0px 5px;">8</li><li 
style="box-sizing: border-box; padding: 0px 5px;">9</li><li 
style="box-sizing: border-box; padding: 0px 5px;">10</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">11</li><li style="box-sizing: border-box; padding: 0px
 5px;">12</li><li style="box-sizing: border-box; padding: 
0px 5px;">13</li><li style="box-sizing: border-box; padding:
 0px 5px;">14</li><li style="box-sizing: border-box; 
padding: 0px 5px;">15</li><li style="box-sizing: border-box;
 padding: 0px 5px;">16</li><li style="box-sizing: 
border-box; padding: 0px 5px;">17</li><li style="box-sizing:
 border-box; padding: 0px 5px;">18</li><li 
style="box-sizing: border-box; padding: 0px 5px;">19</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">20</li><li style="box-sizing: border-box; padding: 0px
 5px;">21</li><li style="box-sizing: border-box; padding: 
0px 5px;">22</li><li style="box-sizing: border-box; padding:
 0px 5px;">23</li><li style="box-sizing: border-box; 
padding: 0px 5px;">24</li><li style="box-sizing: border-box;
 padding: 0px 5px;">25</li><li style="box-sizing: 
border-box; padding: 0px 5px;">26</li><li style="box-sizing:
 border-box; padding: 0px 5px;">27</li><li 
style="box-sizing: border-box; padding: 0px 5px;">28</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">29</li><li style="box-sizing: border-box; padding: 0px
 5px;">30</li><li style="box-sizing: border-box; padding: 
0px 5px;">31</li><li style="box-sizing: border-box; padding:
 0px 5px;">32</li><li style="box-sizing: border-box; 
padding: 0px 5px;">33</li><li style="box-sizing: border-box;
 padding: 0px 5px;">34</li><li style="box-sizing: 
border-box; padding: 0px 5px;">35</li><li style="box-sizing:
 border-box; padding: 0px 5px;">36</li><li 
style="box-sizing: border-box; padding: 0px 5px;">37</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">38</li><li style="box-sizing: border-box; padding: 0px
 5px;">39</li><li style="box-sizing: border-box; padding: 
0px 5px;">40</li><li style="box-sizing: border-box; padding:
 0px 5px;">41</li><li style="box-sizing: border-box; 
padding: 0px 5px;">42</li><li style="box-sizing: border-box;
 padding: 0px 5px;">43</li><li style="box-sizing: 
border-box; padding: 0px 5px;">44</li><li style="box-sizing:
 border-box; padding: 0px 5px;">45</li><li 
style="box-sizing: border-box; padding: 0px 5px;">46</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">47</li><li style="box-sizing: border-box; padding: 0px
 5px;">48</li><li style="box-sizing: border-box; padding: 
0px 5px;">49</li><li style="box-sizing: border-box; padding:
 0px 5px;">50</li><li style="box-sizing: border-box; 
padding: 0px 5px;">51</li><li style="box-sizing: border-box;
 padding: 0px 5px;">52</li><li style="box-sizing: 
border-box; padding: 0px 5px;">53</li><li style="box-sizing:
 border-box; padding: 0px 5px;">54</li><li 
style="box-sizing: border-box; padding: 0px 5px;">55</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">56</li><li style="box-sizing: border-box; padding: 0px
 5px;">57</li><li style="box-sizing: border-box; padding: 
0px 5px;">58</li><li style="box-sizing: border-box; padding:
 0px 5px;">59</li><li style="box-sizing: border-box; 
padding: 0px 5px;">60</li><li style="box-sizing: border-box;
 padding: 0px 5px;">61</li><li style="box-sizing: 
border-box; padding: 0px 5px;">62</li><li style="box-sizing:
 border-box; padding: 0px 5px;">63</li><li 
style="box-sizing: border-box; padding: 0px 5px;">64</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">65</li><li style="box-sizing: border-box; padding: 0px
 5px;">66</li><li style="box-sizing: border-box; padding: 
0px 5px;">67</li><li style="box-sizing: border-box; padding:
 0px 5px;">68</li><li style="box-sizing: border-box; 
padding: 0px 5px;">69</li><li style="box-sizing: border-box;
 padding: 0px 5px;">70</li><li style="box-sizing: 
border-box; padding: 0px 5px;">71</li><li style="box-sizing:
 border-box; padding: 0px 5px;">72</li><li 
style="box-sizing: border-box; padding: 0px 5px;">73</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">74</li><li style="box-sizing: border-box; padding: 0px
 5px;">75</li><li style="box-sizing: border-box; padding: 
0px 5px;">76</li><li style="box-sizing: border-box; padding:
 0px 5px;">77</li><li style="box-sizing: border-box; 
padding: 0px 5px;">78</li><li style="box-sizing: border-box;
 padding: 0px 5px;">79</li><li style="box-sizing: 
border-box; padding: 0px 5px;">80</li><li style="box-sizing:
 border-box; padding: 0px 5px;">81</li><li 
style="box-sizing: border-box; padding: 0px 5px;">82</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">83</li><li style="box-sizing: border-box; padding: 0px
 5px;">84</li><li style="box-sizing: border-box; padding: 
0px 5px;">85</li><li style="box-sizing: border-box; padding:
 0px 5px;">86</li></ul>

基于DFS的顶点排序

人们一般对3种排序感兴趣: 
前序: 在递归调用之前将顶点加入队列。前序就是dfs()的调用顺序。 
后序: 在递归调用之后将顶点加入队列。后序就是顶点遍历完成的顺序。 
逆后序: 在递归调用之后将顶点压入栈。逆后序就是后序的逆序。

它们的实现都非常简单,在原本的dfs()方法中添加3行代码就能实现:

<code
 class="hljs cs has-numbering" style="display: block; padding: 0px; 
color: inherit; box-sizing: border-box; font-family: "Source Code Pro", 
monospace;font-size:undefined; white-space: pre; border-radius: 0px; 
word-wrap: normal; background: transparent;">    <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">public</span> <span class="hljs-keyword" 
style="color: rgb(0, 0, 136); box-sizing: 
border-box;">void</span> <span class="hljs-title" 
style="box-sizing: border-box;">dfs</span>(DiGraph g, <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">int</span> v) {
        pre.enQueue(v);<span class="hljs-comment" style="color: 
rgb(136, 0, 0); box-sizing: 
border-box;">//pre是MyQueue类型的</span>
        marked[s] = <span class="hljs-keyword" style="color: rgb(0, 
0, 136); box-sizing: border-box;">true</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">for</span>(<span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">int</span> w:g.adj(v)){
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">if</span>(!marked(w))
                dfs(g,w);
        }
        post.enQueue(v);
        reversePost.push(v);<span class="hljs-comment" style="color: 
rgb(136, 0, 0); box-sizing: 
border-box;">//MyArrayStack类型</span>
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">public</span> Iterable<Integer> 
<span class="hljs-title" style="box-sizing: 
border-box;">pre</span>(){
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">return</span> pre;
    }
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">public</span> Iterable<Integer> 
<span class="hljs-title" style="box-sizing: 
border-box;">post</span>(){
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">return</span> post;
    }
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">public</span> Iterable<Integer> 
<span class="hljs-title" style="box-sizing: 
border-box;">reversePost</span>(){
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">return</span> reversePost;
    }</code><ul class="pre-numbering" style="box-sizing: 
border-box; position: absolute; width: 50px; top: 0px; left: 0px; 
margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 
221, 221); list-style: none; text-align: right; opacity: 0.30994; 
background-color: rgb(238, 238, 238);"><li style="box-sizing: 
border-box; padding: 0px 5px;">1</li><li style="box-sizing: 
border-box; padding: 0px 5px;">2</li><li style="box-sizing: 
border-box; padding: 0px 5px;">3</li><li style="box-sizing: 
border-box; padding: 0px 5px;">4</li><li style="box-sizing: 
border-box; padding: 0px 5px;">5</li><li style="box-sizing: 
border-box; padding: 0px 5px;">6</li><li style="box-sizing: 
border-box; padding: 0px 5px;">7</li><li style="box-sizing: 
border-box; padding: 0px 5px;">8</li><li style="box-sizing: 
border-box; padding: 0px 5px;">9</li><li style="box-sizing: 
border-box; padding: 0px 5px;">10</li><li style="box-sizing:
 border-box; padding: 0px 5px;">11</li><li 
style="box-sizing: border-box; padding: 0px 5px;">12</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">13</li><li style="box-sizing: border-box; padding: 0px
 5px;">14</li><li style="box-sizing: border-box; padding: 
0px 5px;">15</li><li style="box-sizing: border-box; padding:
 0px 5px;">16</li><li style="box-sizing: border-box; 
padding: 0px 5px;">17</li><li style="box-sizing: border-box;
 padding: 0px 5px;">18</li><li style="box-sizing: 
border-box; padding: 0px 5px;">19</li><li style="box-sizing:
 border-box; padding: 0px 5px;">20</li></ul><ul 
class="pre-numbering" style="box-sizing: border-box; position: absolute;
 width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; 
border-right: 1px solid rgb(221, 221, 221); list-style: none; 
text-align: right; background-color: rgb(238, 238, 238);"><li 
style="box-sizing: border-box; padding: 0px 5px;">1</li><li 
style="box-sizing: border-box; padding: 0px 5px;">2</li><li 
style="box-sizing: border-box; padding: 0px 5px;">3</li><li 
style="box-sizing: border-box; padding: 0px 5px;">4</li><li 
style="box-sizing: border-box; padding: 0px 5px;">5</li><li 
style="box-sizing: border-box; padding: 0px 5px;">6</li><li 
style="box-sizing: border-box; padding: 0px 5px;">7</li><li 
style="box-sizing: border-box; padding: 0px 5px;">8</li><li 
style="box-sizing: border-box; padding: 0px 5px;">9</li><li 
style="box-sizing: border-box; padding: 0px 5px;">10</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">11</li><li style="box-sizing: border-box; padding: 0px
 5px;">12</li><li style="box-sizing: border-box; padding: 
0px 5px;">13</li><li style="box-sizing: border-box; padding:
 0px 5px;">14</li><li style="box-sizing: border-box; 
padding: 0px 5px;">15</li><li style="box-sizing: border-box;
 padding: 0px 5px;">16</li><li style="box-sizing: 
border-box; padding: 0px 5px;">17</li><li style="box-sizing:
 border-box; padding: 0px 5px;">18</li><li 
style="box-sizing: border-box; padding: 0px 5px;">19</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">20</li></ul>

拓扑排序

拓扑排序测试

<code
 class="hljs java has-numbering" style="display: block; padding: 0px; 
color: inherit; box-sizing: border-box; font-family: "Source Code Pro", 
monospace;font-size:undefined; white-space: pre; border-radius: 0px; 
word-wrap: normal; background: transparent;"><span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">package</span> DiGraphs;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">import</span> java.util.Stack;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">public</span> <span class="hljs-class" 
style="box-sizing: border-box;"><span class="hljs-keyword" 
style="color: rgb(0, 0, 136); box-sizing: 
border-box;">class</span> <span class="hljs-title" 
style="box-sizing: border-box; color: rgb(102, 0, 
102);">Topological</span> {</span>

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">private</span> DiGraph g;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">private</span> Iterable<Integer>
 order;<span class="hljs-comment" style="color: rgb(136, 0, 0); 
box-sizing: border-box;">// 拓扑排序序列</span>

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">public</span> <span 
class="hljs-title" style="box-sizing: 
border-box;">Topological</span>(DiGraph g) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">this</span>.g = g;
    }

    <span class="hljs-javadoc" style="color: rgb(136, 0, 0); 
box-sizing: border-box;">/**
     * 返回拓扑排序序列,如果不存在,返回null
     * 
     *<span class="hljs-javadoctag" style="color: rgb(102, 0, 102); 
box-sizing: border-box;"> @return</span>
     */</span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">public</span> Iterable<Integer> 
<span class="hljs-title" style="box-sizing: 
border-box;">order</span>() {
        CycleDetect cd = <span class="hljs-keyword" style="color: 
rgb(0, 0, 136); box-sizing: border-box;">new</span> 
CycleDetect(g);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">if</span> (!cd.hasCycle()) {<span 
class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: 
border-box;">// 如果没有环,就排序</span>
            DiDFSOrder dfsOrder = <span class="hljs-keyword" 
style="color: rgb(0, 0, 136); box-sizing: 
border-box;">new</span> DiDFSOrder(g);
            dfsOrder.dfs();
            order = dfsOrder.reversePost();<span class="hljs-comment"
 style="color: rgb(136, 0, 0); box-sizing: border-box;">// 
dfs的逆后序</span>
        }
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">return</span> order;
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">public</span> <span 
class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
border-box;">static</span> <span class="hljs-keyword" 
style="color: rgb(0, 0, 136); box-sizing: 
border-box;">void</span> <span class="hljs-title" 
style="box-sizing: border-box;">main</span>(String[] args) {
        DiGraph g = <span class="hljs-keyword" style="color: rgb(0, 
0, 136); box-sizing: border-box;">new</span> DiGraph(<span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">8</span>);
        g.addEdge(<span class="hljs-number" style="color: rgb(0, 102,
 102); box-sizing: border-box;">0</span>, <span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">5</span>);
        g.addEdge(<span class="hljs-number" style="color: rgb(0, 102,
 102); box-sizing: border-box;">0</span>, <span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">2</span>);
        g.addEdge(<span class="hljs-number" style="color: rgb(0, 102,
 102); box-sizing: border-box;">0</span>, <span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">4</span>);
        g.addEdge(<span class="hljs-number" style="color: rgb(0, 102,
 102); box-sizing: border-box;">5</span>, <span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">4</span>);
        g.addEdge(<span class="hljs-number" style="color: rgb(0, 102,
 102); box-sizing: border-box;">5</span>, <span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">6</span>);
        g.addEdge(<span class="hljs-number" style="color: rgb(0, 102,
 102); box-sizing: border-box;">2</span>, <span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">3</span>);
        g.addEdge(<span class="hljs-number" style="color: rgb(0, 102,
 102); box-sizing: border-box;">3</span>, <span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">5</span>);
        g.addEdge(<span class="hljs-number" style="color: rgb(0, 102,
 102); box-sizing: border-box;">4</span>, <span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">7</span>);
        g.addEdge(<span class="hljs-number" style="color: rgb(0, 102,
 102); box-sizing: border-box;">6</span>, <span 
class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
border-box;">1</span>);

        Topological t = <span class="hljs-keyword" style="color: 
rgb(0, 0, 136); box-sizing: border-box;">new</span> 
Topological(g);

        Stack<Integer> s = <span class="hljs-keyword" 
style="color: rgb(0, 0, 136); box-sizing: 
border-box;">new</span> Stack<Integer>();
        s = (Stack<Integer>) t.order();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); 
box-sizing: border-box;">while</span> (!s.isEmpty())
            System.out.print(s.pop() + <span class="hljs-string" 
style="color: rgb(0, 136, 0); box-sizing: border-box;">" 
"</span>);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); 
box-sizing: border-box;">//result: 0 2 3 5 6 1 4 7 正确</span>
    }
}</code><ul class="pre-numbering" style="box-sizing: 
border-box; position: absolute; width: 50px; top: 0px; left: 0px; 
margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 
221, 221); list-style: none; text-align: right; opacity: 0.30994; 
background-color: rgb(238, 238, 238);"><li style="box-sizing: 
border-box; padding: 0px 5px;">1</li><li style="box-sizing: 
border-box; padding: 0px 5px;">2</li><li style="box-sizing: 
border-box; padding: 0px 5px;">3</li><li style="box-sizing: 
border-box; padding: 0px 5px;">4</li><li style="box-sizing: 
border-box; padding: 0px 5px;">5</li><li style="box-sizing: 
border-box; padding: 0px 5px;">6</li><li style="box-sizing: 
border-box; padding: 0px 5px;">7</li><li style="box-sizing: 
border-box; padding: 0px 5px;">8</li><li style="box-sizing: 
border-box; padding: 0px 5px;">9</li><li style="box-sizing: 
border-box; padding: 0px 5px;">10</li><li style="box-sizing:
 border-box; padding: 0px 5px;">11</li><li 
style="box-sizing: border-box; padding: 0px 5px;">12</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">13</li><li style="box-sizing: border-box; padding: 0px
 5px;">14</li><li style="box-sizing: border-box; padding: 
0px 5px;">15</li><li style="box-sizing: border-box; padding:
 0px 5px;">16</li><li style="box-sizing: border-box; 
padding: 0px 5px;">17</li><li style="box-sizing: border-box;
 padding: 0px 5px;">18</li><li style="box-sizing: 
border-box; padding: 0px 5px;">19</li><li style="box-sizing:
 border-box; padding: 0px 5px;">20</li><li 
style="box-sizing: border-box; padding: 0px 5px;">21</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">22</li><li style="box-sizing: border-box; padding: 0px
 5px;">23</li><li style="box-sizing: border-box; padding: 
0px 5px;">24</li><li style="box-sizing: border-box; padding:
 0px 5px;">25</li><li style="box-sizing: border-box; 
padding: 0px 5px;">26</li><li style="box-sizing: border-box;
 padding: 0px 5px;">27</li><li style="box-sizing: 
border-box; padding: 0px 5px;">28</li><li style="box-sizing:
 border-box; padding: 0px 5px;">29</li><li 
style="box-sizing: border-box; padding: 0px 5px;">30</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">31</li><li style="box-sizing: border-box; padding: 0px
 5px;">32</li><li style="box-sizing: border-box; padding: 
0px 5px;">33</li><li style="box-sizing: border-box; padding:
 0px 5px;">34</li><li style="box-sizing: border-box; 
padding: 0px 5px;">35</li><li style="box-sizing: border-box;
 padding: 0px 5px;">36</li><li style="box-sizing: 
border-box; padding: 0px 5px;">37</li><li style="box-sizing:
 border-box; padding: 0px 5px;">38</li><li 
style="box-sizing: border-box; padding: 0px 5px;">39</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">40</li><li style="box-sizing: border-box; padding: 0px
 5px;">41</li><li style="box-sizing: border-box; padding: 
0px 5px;">42</li><li style="box-sizing: border-box; padding:
 0px 5px;">43</li><li style="box-sizing: border-box; 
padding: 0px 5px;">44</li><li style="box-sizing: border-box;
 padding: 0px 5px;">45</li><li style="box-sizing: 
border-box; padding: 0px 5px;">46</li><li style="box-sizing:
 border-box; padding: 0px 5px;">47</li><li 
style="box-sizing: border-box; padding: 0px 5px;">48</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">49</li></ul><ul class="pre-numbering" 
style="box-sizing: border-box; position: absolute; width: 50px; top: 
0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px 
solid rgb(221, 221, 221); list-style: none; text-align: right; 
background-color: rgb(238, 238, 238);"><li style="box-sizing: 
border-box; padding: 0px 5px;">1</li><li style="box-sizing: 
border-box; padding: 0px 5px;">2</li><li style="box-sizing: 
border-box; padding: 0px 5px;">3</li><li style="box-sizing: 
border-box; padding: 0px 5px;">4</li><li style="box-sizing: 
border-box; padding: 0px 5px;">5</li><li style="box-sizing: 
border-box; padding: 0px 5px;">6</li><li style="box-sizing: 
border-box; padding: 0px 5px;">7</li><li style="box-sizing: 
border-box; padding: 0px 5px;">8</li><li style="box-sizing: 
border-box; padding: 0px 5px;">9</li><li style="box-sizing: 
border-box; padding: 0px 5px;">10</li><li style="box-sizing:
 border-box; padding: 0px 5px;">11</li><li 
style="box-sizing: border-box; padding: 0px 5px;">12</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">13</li><li style="box-sizing: border-box; padding: 0px
 5px;">14</li><li style="box-sizing: border-box; padding: 
0px 5px;">15</li><li style="box-sizing: border-box; padding:
 0px 5px;">16</li><li style="box-sizing: border-box; 
padding: 0px 5px;">17</li><li style="box-sizing: border-box;
 padding: 0px 5px;">18</li><li style="box-sizing: 
border-box; padding: 0px 5px;">19</li><li style="box-sizing:
 border-box; padding: 0px 5px;">20</li><li 
style="box-sizing: border-box; padding: 0px 5px;">21</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">22</li><li style="box-sizing: border-box; padding: 0px
 5px;">23</li><li style="box-sizing: border-box; padding: 
0px 5px;">24</li><li style="box-sizing: border-box; padding:
 0px 5px;">25</li><li style="box-sizing: border-box; 
padding: 0px 5px;">26</li><li style="box-sizing: border-box;
 padding: 0px 5px;">27</li><li style="box-sizing: 
border-box; padding: 0px 5px;">28</li><li style="box-sizing:
 border-box; padding: 0px 5px;">29</li><li 
style="box-sizing: border-box; padding: 0px 5px;">30</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">31</li><li style="box-sizing: border-box; padding: 0px
 5px;">32</li><li style="box-sizing: border-box; padding: 
0px 5px;">33</li><li style="box-sizing: border-box; padding:
 0px 5px;">34</li><li style="box-sizing: border-box; 
padding: 0px 5px;">35</li><li style="box-sizing: border-box;
 padding: 0px 5px;">36</li><li style="box-sizing: 
border-box; padding: 0px 5px;">37</li><li style="box-sizing:
 border-box; padding: 0px 5px;">38</li><li 
style="box-sizing: border-box; padding: 0px 5px;">39</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">40</li><li style="box-sizing: border-box; padding: 0px
 5px;">41</li><li style="box-sizing: border-box; padding: 
0px 5px;">42</li><li style="box-sizing: border-box; padding:
 0px 5px;">43</li><li style="box-sizing: border-box; 
padding: 0px 5px;">44</li><li style="box-sizing: border-box;
 padding: 0px 5px;">45</li><li style="box-sizing: 
border-box; padding: 0px 5px;">46</li><li style="box-sizing:
 border-box; padding: 0px 5px;">47</li><li 
style="box-sizing: border-box; padding: 0px 5px;">48</li><li
 style="box-sizing: border-box; padding: 0px 
5px;">49</li></ul>

总结

拓扑排序并不是一个困难的算法,在后面的加权有向图的最短路径问题中还会遇到它。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值