I have a set of items and a comparator function which defines a partial ordering -- given two items, it returns "=", "<", ">", or "no defined ordering" (say "<>"). I want to produce a sorted list of items that respects this partial ordering.
If I look for algorithms to do a topological sort, they generally start with a directed acyclic graph. But I don't have a DAG, and I can't see a simple way to construct one without doing a large number (N*N perhaps?) of comparisons. What I would like is some kind of QuickSort-like algorithm that works by comparing and swapping selected items in a list. Is there such an algorithm? I'm assuming most classical sorting algorithms would fail because of the indeterminism.
I thought of trying to use a classical sort algorithm and treating "<>" as "=", but it doesn't work because I can have the situation A < B, A <> C, B <> C, so I can't treat C as being equal to both A and B.
Any ideas or pointers?
A topological ordering is possible if and only if the graph has no directed cycles, that is, if it is a directed acyclic graph (DAG).
If the graph has a cycle, a topological order cannot exist. Imagine the simplest cycle, consist- ing of two edges: (a, b) and (b, a). A topological ordering , if it existed, would have to satisfy that a must come before b and b must come before a. This is not possible.
The topological sort algorithm takes a directed graph and returns an array of the nodes where each node appears before all the nodes it points to. The ordering of the nodes in the array is called a topological ordering.
Topological Sorting is possible if and only if the graph is a Directed Acyclic Graph. There may exist multiple different topological orderings for a given directed acyclic graph.
You don't need to create a graph explicitly to use topological sort algorithm.
Let S
be the set of elements you want to sort, and there is a partial order in S
. Let used
be the dictionary that maps each element from S
to a boolean value (false
by default) that will be true
when we visit a 'node' with this element. Let stack
be the stack of elements from S
(empty by default).
Define a method dfs(x)
(x
is an element of S
) that does the following:
Set used[x]
to true
For each element y
in S
:
If used[y]
is false
and x
is less than or equal to y
(*):
dfs(y)
Add x
to stack
Then:
For each element x
in S
:
If used[x]
is false
:
dfs(x)
After this loop, elements in stack
will be ordered (first item to be popped from stack
is minimal one (not necessarily minimum), last item is maximal one (not necessarily maximum)).
This algorithm obviously runs in O(n^2) because it's still a topological sort, just without creating graph explicitly.
(*): Like topological sort processes only edges that go from x
to y
and does not process cases where edge goes from y
to x
or there is no edge at all, this algorithm processes only 'less than or equal to' relations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With