有向无环图的拓扑排序

时间:2014-07-16 17:41:32

标签: sorting topological-sort

对于有向无环图G,是否可能有不同的拓扑排序?例如,在图表中:

A --> B --> D
      B --> E
A --> C --> E

我认为拓扑排序取决于运行深度优先搜索算法后每个顶点的完成时间。不是每个完成时间都是唯一的,因此只有一个拓扑排序可能吗?

2 个答案:

答案 0 :(得分:0)

是肯定的。您可以通过多种方式遍历图表。

在您的示例中,您可以拥有A,B,......或A,C,......

关于拓扑排序的维基百科页面有一个更好的例子:  http://en.wikipedia.org/wiki/Topological_sorting

从上面引用的维基页面:

  

如果拓扑排序具有所有连续对的属性   排序顺序中的顶点通过边连接,然后连接这些边   在DAG中形成有向哈密顿路径。如果是哈密尔顿路径   存在,拓扑排序顺序是唯一的;没有其他订单尊重   路径的边缘。相反,如果不形成拓扑排序   在哈密顿路径中,DAG将具有两个或更多有效拓扑   排序,在这种情况下,总是可以形成第二个   通过交换两个不连续的顶点进行有效排序   通过边缘相互连接。因此,有可能进行测试   在线性时间内是否存在唯一的排序,以及是否存在   尽管哈密顿量的NP-硬度存在哈密顿路径   更一般有向图的路径问题(Vernet& Markenzon   1997年)。

答案 1 :(得分:0)

public class TopologicalSort
{
    private int V;   // No. of vertices
    private List<int> [] adj; // Adjacency List

    public ToplogicalSort(int v)
    {
        V = v;
        adj = new List<int>[v];
        for (int i=0; i < v; ++i)
            adj[i] = new List<int>();
    }

    public void AddEdge(int v,int w) { adj[v].Add(w); }

    public void TopologicalSortUtil(int v, bool[] visited, Stack<int> stack)
    {
        Stack<int> stackTracing = new Stack<int>();
        bool res = true;
        List<int> list = new List<int>(adj[v]);
        stackTracing.Push(v);
        while (stackTracing.Count != 0 | res)
        {
            int n = stackTracing.Peek();
            list = new List<int>(adj[n]);
            bool check = false;
            foreach (var elem in list)
            {
                if (!visited[elem])
                {
                    visited[elem] = true;
                    n = elem;
                    stackTracing.Push(elem);
                    check = true;
                    break;
                }
            }

            if(!check)
            {
                if(!stack.Contains(n))
                {
                    stack.Push(n);
                }
                if (stackTracing.Count != 0)
                    stackTracing.Pop();
                res = false;
            }           
        }
    }

    public void TopologicalSort()
    {
        Stack<int> stack = new Stack<int>();
        bool[] visited = new bool[V];
        for (int i = 0; i < V; i++)
            visited[i] = false;

        for (int i = 0; i < V; i++)
        {
            if (visited[i] == false)
            {
                topologicalSortUtil(i, visited, stack);
            }
        }
        // Print contents of stack
        while (stack.Count != 0)
        {
            stack.Pop();
            Console.WriteLine(stack.Pop() + " ");
        }
    }
    public static void RunSort()
    {
        TopologicalSort g = new TopologicalSort(6);
        g.AddEdge(5, 2);
        g.AddEdge(5, 0);
        g.AddEdge(4, 0);
        g.AddEdge(4, 1);
        g.AddEdge(2, 3);
        g.AddEdge(3, 1);
        g.TopologicalSort();
    }
}