Topologisk sortering för Regisserad acyklisk graf (DAG) är en linjär ordning av hörn så att för varje riktad kant u-v, vertex i kommer före i i beställningen.
Notera: Topologisk sortering för en graf är inte möjlig om grafen inte är en DAG .
linux byta namn på mapp
Exempel:
Rekommenderad praxisDFS-baserad lösning för att hitta en topologisk sort har redan diskuterats.Inmatning: Graf :
Exempel
Produktion: 5 4 2 3 1 0
Förklaring: Den första vertexen i topologisk sortering är alltid en vertex med en in-grad på 0 (en vertex utan inkommande kanter). En topologisk sortering av följande graf är 5 4 2 3 1 0. Det kan finnas mer än en topologisk sortering för en graf. En annan topologisk sortering av följande graf är 4 5 2 3 1 0.
Topologisk ordning kanske inte är unik:
Topologisk sortering är ett beroendeproblem där slutförandet av en uppgift beror på slutförandet av flera andra uppgifter vars ordningsföljd kan variera. Låt oss förstå detta koncept med ett exempel:
Anta att vår uppgift är att nå vår skola och för att nå dit måste vi först klä på oss. Beroendena att bära kläder visas i beroendediagrammet nedan. Till exempel kan du inte bära skor innan du bär strumpor.
Från bilden ovan skulle du redan ha insett att det finns flera sätt att klä på sig, bilden nedan visar några av dessa sätt.
Kan du lista all möjlig topologisk ordning av att klä på sig för ovanstående beroendediagram?
Algoritm för topologisk sortering med DFS:
Här är en steg-för-steg-algoritm för topologisk sortering med Depth First Search (DFS):
- Skapa en graf med n hörn och m -riktade kanter.
- Initiera en stack och en besökt array av storlek n .
- Gör följande för varje obesökt hörn i grafen:
- Anropa DFS-funktionen med vertex som parameter.
- I DFS-funktionen markerar du vertexet som besökt och anropar DFS-funktionen rekursivt för alla obesökta grannar till vertexet.
- När alla grannar har besökts trycker du spetsen på traven.
- När allt kommer omkring, hörn har besökts, poppar element från stacken och lägg till dem i utdatalistan tills stacken är tom.
- Den resulterande listan är den topologiskt sorterade ordningen för grafen.
Illustration Topologisk sorteringsalgoritm:
Bilden nedan är en illustration av ovanstående tillvägagångssätt:

Övergripande arbetsflöde av topologisk sortering
Steg 1:
- Vi startar DFS från nod 0 eftersom den har noll inkommande noder
- Vi trycker på nod 0 i stacken och flyttar till nästa nod som har minsta antal intilliggande noder, dvs nod 1.
Steg 2:
- I det här steget, eftersom det inte finns någon angränsande till denna nod, tryck nod 1 i stacken och flytta till nästa nod.
Steg 3:
- I det här steget väljer vi nod 2 eftersom den har minsta antal intilliggande noder efter 0 och 1.
- Vi anropar DFS för nod 2 och trycker på alla noder som kommer i korsning från nod 2 i omvänd ordning.
- Så tryck 3 och tryck sedan 2 .
Steg 4:
- Vi kallar nu DFS för nod 4
- Eftersom 0 och 1 redan finns i stacken så vi trycker bara på nod 4 i stacken och går tillbaka.
Steg 5:
- I detta steg, eftersom alla intilliggande noder av 5 redan finns i stacken, trycker vi nod 5 i stacken och går tillbaka.
Steg 6: Detta är det sista steget i den topologiska sorteringen där vi poppar alla element från stapeln och skriver ut det i den ordningen.
beräkning av anställning i excel
Nedan är implementeringen av ovanstående tillvägagångssätt:
C++ #include using namespace std; // Function to perform DFS and topological sorting void topologicalSortUtil(int v, vector>& adj, vektor & besökte, stack & Stack) { // Markera den aktuella noden som besökt besökt[v] = sant; // Återkommande för alla angränsande hörn för (int i : adj[v]) { if (!besökt[i]) topologicalSortUtil(i, adj, besökt, Stack); } // Tryck aktuell vertex till stack som lagrar resultatet Stack.push(v); } // Funktion för att utföra Topological Sort void topologicalSort(vector>& adj, int V) { stack Stack; // Stapla för att lagra resultatvektorn besökt(V, falskt); // Anropa den rekursiva hjälpfunktionen för att lagra // Topologisk sortering med början från alla hörn en efter // en för (int i = 0; i< V; i++) { if (!visited[i]) topologicalSortUtil(i, adj, visited, Stack); } // Print contents of stack while (!Stack.empty()) { cout << Stack.top() << ' '; Stack.pop(); } } int main() { // Number of nodes int V = 4; // Edges vector> kanter = { { 0, 1 }, { 1, 2 }, { 3, 1 }, { 3, 2 } }; // Graf representerad som en angränsande listvektor> adj(V); for (auto i : kanter) { adj[i[0]].push_back(i[1]); } cout<< 'Topological sorting of the graph: '; topologicalSort(adj, V); return 0; }>
Java import java.util.*; public class TopologicalSort { // Function to perform DFS and topological sorting static void topologicalSortUtil(int v, List> adj, boolesk[] besökt, Stack stack) { // Markera den aktuella noden som besökt besökt[v] = sant; // Återkommande för alla angränsande hörn för (int i : adj.get(v)) { if (!besökt[i]) topologicalSortUtil(i, adj, besökt, stack); } // Tryck aktuell vertex till stack som lagrar //-resultatet stack.push(v); } // Funktion för att utföra Topological Sort static void topologicalSort(List> adj, int V) { // Stack för att lagra resultatet Stack stack = ny stack(); boolean[] besökt = new boolean[V]; // Anropa den rekursiva hjälpfunktionen för att lagra // Topologisk sortering med början från alla hörn en // i taget för (int i = 0; i< V; i++) { if (!visited[i]) topologicalSortUtil(i, adj, visited, stack); } // Print contents of stack System.out.print( 'Topological sorting of the graph: '); while (!stack.empty()) { System.out.print(stack.pop() + ' '); } } // Driver code public static void main(String[] args) { // Number of nodes int V = 4; // Edges List> edges = new ArrayList(); edges.add(Arrays.asList(0, 1)); edges.add(Arrays.asList(1, 2)); edges.add(Arrays.asList(3, 1)); edges.add(Arrays.asList(3, 2)); // Grafen representerad som en lista över angränsande listor> adj = ny ArrayList(V); för (int i = 0; i< V; i++) { adj.add(new ArrayList()); } for (List i : edges) { adj.get(i.get(0)).add(i.get(1)); } topologicalSort(adj, V); } }>
Python3 def topologicalSortUtil(v, adj, visited, stack): # Mark the current node as visited visited[v] = True # Recur for all adjacent vertices for i in adj[v]: if not visited[i]: topologicalSortUtil(i, adj, visited, stack) # Push current vertex to stack which stores the result stack.append(v) # Function to perform Topological Sort def topologicalSort(adj, V): # Stack to store the result stack = [] visited = [False] * V # Call the recursive helper function to store # Topological Sort starting from all vertices one by # one for i in range(V): if not visited[i]: topologicalSortUtil(i, adj, visited, stack) # Print contents of stack print('Topological sorting of the graph:', end=' ') while stack: print(stack.pop(), end=' ') # Driver code if __name__ == '__main__': # Number of nodes V = 4 # Edges edges = [[0, 1], [1, 2], [3, 1], [3, 2]] # Graph represented as an adjacency list adj = [[] for _ in range(V)] for i in edges: adj[i[0]].append(i[1]) topologicalSort(adj, V)> C# using System; using System.Collections.Generic; class Program { // Function to perform DFS and topological sorting static void TopologicalSortUtil(int v, List> adj, bool[] besökt, Stack stack) { // Markera den aktuella noden som besökt besökt[v] = sant; // Återkommande för alla intilliggande hörn foreach(int i i adj[v]) { if (!besökt[i]) TopologicalSortUtil(i, adj, besökt, stack); } // Tryck aktuell vertex till stack som lagrar //-resultatstacken.Push(v); } // Funktion för att utföra Topological Sort static void TopologicalSort(List> adj, int V) { // Stack för att lagra resultatet Stack stack = ny stack (); bool[] besökt = ny bool[V]; // Anropa den rekursiva hjälpfunktionen för att lagra // Topologisk sortering med början från alla hörn en // i taget för (int i = 0; i< V; i++) { if (!visited[i]) TopologicalSortUtil(i, adj, visited, stack); } // Print contents of stack Console.Write('Topological sorting of the graph: '); while (stack.Count>0) { Console.Write(stack.Pop() + ' '); } } // Driver code static void Main(string[] args) { // Antal noder int V = 4; // Kantlista> kanter = ny lista>{ ny lista { 0, 1 }, ny lista { 1, 2 }, ny lista { 3, 1 }, ny lista { 3, 2 } }; // Grafen representerad som en lista över angränsande listor> adj = ny lista>(); för (int i = 0; i< V; i++) { adj.Add(new List ()); } foreach(List i i kanter) { adj[i[0]].Add(i[1]); } TopologicalSort(adj, V); } }>
Javascript // Function to perform DFS and topological sorting function topologicalSortUtil(v, adj, visited, stack) { // Mark the current node as visited visited[v] = true; // Recur for all adjacent vertices for (let i of adj[v]) { if (!visited[i]) topologicalSortUtil(i, adj, visited, stack); } // Push current vertex to stack which stores the result stack.push(v); } // Function to perform Topological Sort function topologicalSort(adj, V) { // Stack to store the result let stack = []; let visited = new Array(V).fill(false); // Call the recursive helper function to store // Topological Sort starting from all vertices one by // one for (let i = 0; i < V; i++) { if (!visited[i]) topologicalSortUtil(i, adj, visited, stack); } // Print contents of stack console.log('Topological sorting of the graph: '); while (stack.length>0) { console.log(stack.pop() + ' '); } } // Förarkod (() => { // Antal noder const V = 4; // Edges const edges = [[0, 1], [1, 2], [3, 1], [3, 2]]; // Graph representerad som en adjacency list const adj = Array.from({ length: V }, () => []); (i[1]); } topologicalSort(adj, V })();> Produktion
Topological sorting of the graph: 3 0 1 2>
Tidskomplexitet: O(V+E). Algoritmen ovan är helt enkelt DFS med en extra stack. Så tidskomplexitet är detsamma som DFS
Extra utrymme: O(V). Det extra utrymmet behövs för stapeln
Topologisk sortering med BFS:
C++ #include #include #include using namespace std; // Class to represent a graph class Graph { int V; // No. of vertices list * adj; // Pekare till en array som innehåller // adjacency lists public: Graph(int V); // Konstruktör void addEdge(int v, int w); // Funktion för att lägga till en kant till grafen void topologicalSort(); // skriver ut en topologisk sort av // hela grafen }; Graph::Graph(int V) { this->V = V; adj = ny lista [V]; } void Graph::addEdge(int v, int w) { adj[v].push_back(w); // Lägg till w till vs lista. } // Funktion för att utföra Topological Sort void Graph::topologicalSort() { // Skapa en vektor för att lagra i grader av alla vertexvektorer in_degree(V, 0); // Gå igenom närliggande listor för att fylla i_grad av // hörn för (int v = 0; v< V; ++v) { for (auto const& w : adj[v]) in_degree[w]++; } // Create a queue and enqueue all vertices with // in-degree 0 queue q; för (int i = 0; i< V; ++i) { if (in_degree[i] == 0) q.push(i); } // Initialize count of visited vertices int count = 0; // Create a vector to store topological order vector top_order; // En efter en dequeue vertices from queue and enqueue // angränsande hörn om in-degree of adjacent blir 0 medan (!q.empty()) { // Extrahera framsidan av kön (eller utför dequeue) // och lägg till den till topologisk ordning int u = q.front(); q.pop(); top_order.push_back(u); // Iterera genom alla dess närliggande noder // av nod u från kö och minska deras in-grad // med 1 lista ::iterator itr; for (itr = adj[u].begin(); itr != adj[u].end(); ++itr) // Om in-graden blir noll, lägg till den i kön if (--in_degree[*itr) ] == 0) q.push(*itr); räkna++; } // Kontrollera om det fanns en cykel if (count != V) { cout<< 'Graph contains cycle
'; return; } // Print topological order for (int i : top_order) cout << i << ' '; } // Driver code int main() { // Create a graph given in the above diagram Graph g(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); cout << 'Following is a Topological Sort of the given ' 'graph
'; g.topologicalSort(); return 0; }> Java import java.util.ArrayList; import java.util.LinkedList; import java.util.Queue; // Class to represent a graph class Graph { private int V; // No. of vertices private ArrayList [] adj; // Adjacency list // representation of // the graph // Constructor Graph(int V) { this.V = V; adj = ny ArrayList[V]; för (int i = 0; i< V; ++i) adj[i] = new ArrayList(); } // Function to add an edge to the graph void addEdge(int v, int w) { adj[v].add(w); // Add w to v’s list. } // Function to perform Topological Sort void topologicalSort() { // Create an array to store in-degree of all // vertices int[] inDegree = new int[V]; // Calculate in-degree of each vertex for (int v = 0; v < V; ++v) { for (int w : adj[v]) { inDegree[w]++; } } // Create a queue and enqueue all vertices with // in-degree 0 Queue q = new LinkedList(); för (int i = 0; i< V; ++i) { if (inDegree[i] == 0) q.add(i); } // Initialize count of visited vertices int count = 0; // Create an ArrayList to store topological order ArrayList topOrder = new ArrayList(); // En efter en avköa hörn från kön och // ställ in angränsande hörn i kö om in-graden av // adjacent blir 0 medan (!q.isEmpty()) { // Extrahera köns framsida och lägg till den i // topologisk ordning int u = q.poll(); topOrder.add(u); räkna++; // Iterera genom alla dess närliggande noder av // ur kö nod u och minska deras in-grad // med 1 för (int w : adj[u]) { // Om in-graden blir noll, lägg till den i //-kön if (-inDegree[w] == 0) q.add(w); } } // Kontrollera om det fanns en cykel if (count != V) { System.out.println('Graf innehåller cykel'); lämna tillbaka; } // Skriv ut topologisk ordning för (int i : topOrder) System.out.print(i + ' '); } } // Driver code public class Main { public static void main(String[] args) { // Skapa en graf som ges i diagrammet ovan. Graph g = new Graph(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); System.out.println( 'Följande är en topologisk sortering av den givna grafen'); g.topologicalSort(); } }> Python3 from collections import defaultdict class Graph: def __init__(self, vertices): # Number of vertices self.V = vertices # Dictionary to store adjacency lists self.adj = defaultdict(list) def addEdge(self, u, v): # Function to add an edge to the graph self.adj[u].append(v) def topologicalSort(self): # Function to perform Topological Sort # Create a list to store in-degree of all vertices in_degree = [0] * self.V # Traverse adjacency lists to fill in_degree of vertices for i in range(self.V): for j in self.adj[i]: in_degree[j] += 1 # Create a queue and enqueue all vertices with in-degree 0 q = [] for i in range(self.V): if in_degree[i] == 0: q.append(i) # Initialize count of visited vertices count = 0 # Create a list to store topological order top_order = [] # One by one dequeue vertices from queue and enqueue # adjacent vertices if in-degree of adjacent becomes 0 while q: # Extract front of queue (or perform dequeue) # and add it to topological order u = q.pop(0) top_order.append(u) # Iterate through all its neighbouring nodes # of dequeued node u and decrease their in-degree # by 1 for node in self.adj[u]: # If in-degree becomes zero, add it to queue in_degree[node] -= 1 if in_degree[node] == 0: q.append(node) count += 1 # Check if there was a cycle if count != self.V: print('Graph contains cycle') return # Print topological order print('Topological Sort:', top_order) # Driver code if __name__ == '__main__': # Create a graph given in the above diagram g = Graph(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) print('Following is a Topological Sort of the given graph') g.topologicalSort()> JavaScript // Class to represent a graph class Graph { constructor(V) { this.V = V; // No. of vertices this.adj = new Array(V); // Array containing adjacency lists for (let i = 0; i < V; i++) { this.adj[i] = []; } } // Function to add an edge to the graph addEdge(v, w) { this.adj[v].push(w); // Add w to v’s list. } // Function to perform Topological Sort topologicalSort() { // Create a array to store in-degree of all vertices let inDegree = new Array(this.V).fill(0); // Traverse adjacency lists to fill inDegree of vertices for (let v = 0; v < this.V; v++) { for (let w of this.adj[v]) { inDegree[w]++; } } // Create a queue and enqueue all vertices with in-degree 0 let queue = []; for (let i = 0; i < this.V; i++) { if (inDegree[i] === 0) { queue.push(i); } } // Initialize count of visited vertices let count = 0; // Create an array to store topological order let topOrder = []; // One by one dequeue vertices from queue and enqueue // adjacent vertices if in-degree of adjacent becomes 0 while (queue.length !== 0) { // Extract front of queue and add it to topological order let u = queue.shift(); topOrder.push(u); // Iterate through all its neighboring nodes // of dequeued node u and decrease their in-degree by 1 for (let w of this.adj[u]) { // If in-degree becomes zero, add it to queue if (--inDegree[w] === 0) { queue.push(w); } } count++; } // Check if there was a cycle if (count !== this.V) { console.log('Graph contains cycle'); return; } // Print topological order console.log('Topological Sort of the given graph:'); console.log(topOrder.join(' ')); } } // Driver code // Create a graph given in the above diagram let g = new Graph(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); console.log('Following is a Topological Sort of the given graph:'); g.topologicalSort(); //This code is contributed by Utkarsh> Produktion
Following is a Topological Sort of the given graph 4 5 2 0 3 1>
Tidskomplexitet:
Tidskomplexiteten för att konstruera grafen är O(V + E), där V är antalet hörn och E är antalet kanter.
Tidskomplexiteten för att utföra topologisk sortering med BFS är också O(V + E), där V är antalet hörn och E är antalet kanter. Detta beror på att varje vertex och varje kant besöks en gång under BFS-genomgången.
Utrymmes komplexitet:
Utrymmeskomplexiteten för att lagra grafen med hjälp av en närliggande lista är O(V + E), där V är antalet hörn och E är antalet kanter.
Ytterligare utrymme används för att lagra in-graden av hörn, vilket kräver O(V) utrymme.
En kö används för BFS-traversal, som kan innehålla högst V-punkt. Sålunda är utrymmeskomplexiteten för kön O(V).
Totalt sett är rymdkomplexiteten för algoritmen O(V + E) på grund av lagringen av grafen, in-gradersmatrisen och kön.
Sammanfattningsvis är tidskomplexiteten för den tillhandahållna implementeringen O(V + E), och rymdkomplexiteten är också O(V + E).
Notera: Här kan vi också använda en array istället för stacken. Om arrayen används, skriv ut elementen i omvänd ordning för att få den topologiska sorteringen.
Fördelar med topologisk sortering:
- Hjälper till att schemalägga uppgifter eller händelser baserat på beroenden.
- Upptäcker cykler i en riktad graf.
- Effektiv för att lösa problem med prioritetsbegränsningar.
Nackdelar med topologisk sortering:
- Gäller endast riktade acykliska grafer (DAGs), inte lämpliga för cykliska grafer.
- Kanske inte är unik, flera giltiga topologiska ordningar kan existera.
- Ineffektivt för stora grafer med många noder och kanter.
Tillämpningar av topologisk sort:
- Uppgiftsschemaläggning och projektledning.
- Beroendelösning i pakethanteringssystem.
- Bestämma ordningen för kompilering i mjukvarubyggsystem.
- Detektering av dödläge i operativsystem.
- Kursplanering vid universitet.
Relaterade artiklar:
- Kahns algoritm för topologisk sortering
- Alla topologiska sorter av en riktad acyklisk graf





