← Back to DSA Course | Chapter 13: Graphs | Lesson 6 of 10

Topological Sort क्या है

एक topological sort chores को इस तरह order करने जैसा है कि आप हमेशा वे पहले खत्म करें जो पहले आने चाहिए, जैसे shoes से पहले socks पहनना।
Syntax
markup
from collections import deque
queue = deque(v for v in graph if indegree[v] == 0)
order = []
while queue:
    node = queue.popleft()
    order.append(node)
    for nxt in graph[node]:
        indegree[nxt] -= 1
        if indegree[nxt] == 0:
            queue.append(nxt)

What is Topological Sort

एक topological sort एक directed acyclic graph की vertices को एक line में इस तरह arrange करता है कि हर edge एक पहले वाले vertex से एक बाद वाले की ओर point करे — इसे courses लेने का एक valid order सोचें उनकी prerequisites को देखते हुए।

उदाहरण: What is Topological Sort

#include <iostream>
using namespace std;
int main() {
	// Courses: 0=Intro, 1=DataStructures(needs 0), 2=Algorithms(needs 1)
	int order[] = {0, 1, 2};
	cout << "Valid order: ";
	for (int c : order) cout << c << " ";
	return 0;
}
public class Main {
	public static void main(String[] args) {
		int[] order = {0, 1, 2};
		System.out.print("Valid order: ");
		for (int c : order) System.out.print(c + " ");
	}
}
order = [0, 1, 2]
print("Valid order:", *order)
#include <stdio.h>
int main() {
	int order[] = {0, 1, 2};
	printf("Valid order: ");
	for (int i = 0; i < 3; i++) printf("%d ", order[i]);
	return 0;
}

Indegree

किसी vertex का indegree यह count करता है कि इसमें कितने edges point करते हैं, जो बिल्कुल उतनी ही prerequisites की संख्या है जो उस vertex के ordering में सुरक्षित रूप से दिखने से पहले अब भी satisfy होनी चाहिए।

उदाहरण: Indegree

#include <iostream>
using namespace std;
int main() {
	int indegree[3] = {0, 1, 1};
	cout << "Vertex 1 needs " << indegree[1] << " prerequisite(s) satisfied first";
	return 0;
}
public class Main {
	public static void main(String[] args) {
		int[] indegree = {0, 1, 1};
		System.out.println("Vertex 1 needs " + indegree[1] + " prerequisite(s) satisfied first");
	}
}
indegree = [0, 1, 1]
print(f"Vertex 1 needs {indegree[1]} prerequisite(s) satisfied first")
#include <stdio.h>
int main() {
	int indegree[3] = {0, 1, 1};
	printf("Vertex 1 needs %d prerequisite(s) satisfied first", indegree[1]);
	return 0;
}

Kahn's Algorithm

Kahn का algorithm बार-बार indegree zero वाला एक vertex हटाता है (इसे block करने वाला कुछ नहीं बचा), इसे output में जोड़ता है, और इसके neighbors की indegree घटाता है, सभी currently-available vertices रखने के लिए एक queue उपयोग करते हुए।

उदाहरण: Kahn's Algorithm

#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int main() {
	vector<vector<int>> adj = {{1},{2},{}};
	vector<int> indegree = {0,1,1};
	queue<int> q; vector<int> output;
	for (int i = 0; i < 3; i++) if (indegree[i] == 0) q.push(i);
	while (!q.empty()) {
		int u = q.front(); q.pop();
		output.push_back(u);
		for (int v : adj[u]) if (--indegree[v] == 0) q.push(v);
	}
	for (int v : output) cout << v << " ";
	return 0;
}
import java.util.*;
public class Main {
	public static void main(String[] args) {
		List<List<Integer>> adj = Arrays.asList(Arrays.asList(1), Arrays.asList(2), Arrays.asList());
		int[] indegree = {0,1,1};
		Queue<Integer> q = new LinkedList<>();
		List<Integer> output = new ArrayList<>();
		for (int i = 0; i < 3; i++) if (indegree[i] == 0) q.add(i);
		while (!q.isEmpty()) {
			int u = q.poll();
			output.add(u);
			for (int v : adj.get(u)) if (--indegree[v] == 0) q.add(v);
		}
		System.out.println(output);
	}
}
from collections import deque
adj = [[1],[2],[]]
indegree = [0,1,1]
q = deque(i for i in range(3) if indegree[i] == 0)
output = []
while q:
    u = q.popleft()
    output.append(u)
    for v in adj[u]:
        indegree[v] -= 1
        if indegree[v] == 0:
            q.append(v)
print(*output)
#include <stdio.h>
int main() {
	int adj[3][1] = {{1},{2},{-1}};
	int indegree[3] = {0,1,1}, queue[3], front=0, back=0, output[3], n=0;
	for (int i = 0; i < 3; i++) if (indegree[i] == 0) queue[back++] = i;
	while (front < back) {
		int u = queue[front++];
		output[n++] = u;
		if (adj[u][0] != -1 && --indegree[adj[u][0]] == 0) queue[back++] = adj[u][0];
	}
	for (int i = 0; i < n; i++) printf("%d ", output[i]);
	return 0;
}

Cycle Check

अगर algorithm हर vertex रखे बिना खत्म हो जाए, कुछ vertices की indegrees कभी zero नहीं पहुंचीं — मतलब वे एक cycle में फंसी हैं, इसलिए उस graph के लिए एक topological order बस मौजूद नहीं हो सकता।

उदाहरण: Cycle Check

#include <iostream>
using namespace std;
int main() {
	int placed = 2, total = 3;
	if (placed < total) cout << "Only " << placed << "/" << total << " placed: remaining vertices stuck in a cycle";
	return 0;
}
public class Main {
	public static void main(String[] args) {
		int placed = 2, total = 3;
		if (placed < total) System.out.println("Only " + placed + "/" + total + " placed: remaining vertices stuck in a cycle");
	}
}
placed, total = 2, 3
if placed < total:
    print(f"Only {placed}/{total} placed: remaining vertices stuck in a cycle")
#include <stdio.h>
int main() {
	int placed = 2, total = 3;
	if (placed < total) printf("Only %d/%d placed: remaining vertices stuck in a cycle", placed, total);
	return 0;
}

Applications

Build systems files को उनकी dependencies के बाद ही compile करने के लिए topological order उपयोग करते हैं, और course-scheduling systems हर prerequisite respect करने वाला classes का एक legal sequence ढूंढने के लिए इसे उपयोग करते हैं।

उदाहरण: Applications

#include <iostream>
using namespace std;
int main() {
	cout << "Build systems compile files after dependencies; scheduling finds a legal class sequence";
	return 0;
}
public class Main {
	public static void main(String[] args) {
		System.out.println("Build systems compile files after dependencies; scheduling finds a legal class sequence");
	}
}
print("Build systems compile files after dependencies; scheduling finds a legal class sequence")
#include <stdio.h>
int main() {
	printf("Build systems compile files after dependencies; scheduling finds a legal class sequence");
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. एक cycle वाले graph पर topological sort चलाना, जब यह सिर्फ एक DAG के लिए defined है।
  2. यह न जांचना कि output में सभी V vertices हैं, इसलिए एक cycle अनदेखा रह जाता है।
  3. एक vertex हटाने के बाद neighbours की indegree घटाना भूल जाना।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.