DSA Interview Prep · पाठ

Kahn का एल्गोरिदम: BFS टोपोलॉजिकल सॉर्ट

सभी नोडों की इन-डिग्री निकालिए, शून्य इन-डिग्री वाले नोडों को कतार में डालिए और चक्रों का पता लगाते हुए टोपोलॉजिकल क्रम बनाने के लिए कतार को संसाधित कीजिए।

पाठ 1, कुल 4 में से13 चरण

Kahn का एल्गोरिदम: BFS टोपोलॉजिकल सॉर्ट, CoddyKit पर DSA Interview Prep का एक निःशुल्क पाठ है। यह 4 में से 1वाँ पाठ है। इस अध्ययन पथ के 3 तक कोई भी पाठ पूरा पढ़ना निःशुल्क है — इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ व्यावहारिक अभ्यास भी उपलब्ध कराता है। यह DSA Interview Prep सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। DSA Interview Prep पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

टोपोलॉजिकल क्रमण क्या है

दिशित अचक्रीय ग्राफ (DAG) का टोपोलॉजिकल क्रमण उसके नोडों का ऐसा क्रम है जिसमें प्रत्येक दिशित किनारे u → v का अर्थ है कि क्रम में u, v से पहले आता है। यह निर्भरताओं वाले कार्यों के लिए मान्य निष्पादन क्रम दर्शाता है — जैसे निर्माण प्रणालियाँ, पाठ्यक्रम निर्धारण या पैकेज प्रबंधन। केवल DAG का ही मान्य टोपोलॉजिकल क्रम हो सकता है; कोई चक्र इसे असंभव बना देता है।

कान का एल्गोरिदम: मूल विचार

कान का एल्गोरिदम टोपोलॉजिकल क्रमण के लिए BFS-आधारित विधि है। मुख्य विचार यह है: 0 इन-डिग्री वाला नोड (जिसकी कोई पूर्वापेक्षा नहीं है) क्रम में सबसे पहले रखा जा सकता है। उसे रखने के बाद उसे हटा दें और उसके पड़ोसी नोडों की इन-डिग्री घटाएँ। जिन नए नोडों की इन-डिग्री शून्य हो जाती है, वे उपलब्ध हो जाते हैं। यह प्रक्रिया तब तक दोहराएँ जब तक सभी नोड रख न दिए जाएँ या चक्र का पता न चल जाए (कुछ नोडों की इन-डिग्री शून्य से अधिक बनी रहती है)।

इन-डिग्री की गणना

पहले आसन्नता सूची बनाएँ और प्रत्येक नोड की इन-डिग्री (अंदर आने वाले किनारों की संख्या) निकालें। 0 इन-डिग्री वाले नोड शुरुआती बिंदु होते हैं — उन पर कोई निर्भरता नहीं होती। किनारों वाले ग्राफ [(0,1),(0,2),(1,3),(2,3)] के लिए इन-डिग्री इस प्रकार हैं: 0→0, 1→1, 2→1, 3→2। केवल नोड 0 की शुरुआत 0 इन-डिग्री से होती है।

from collections import deque, defaultdict

def compute_in_degree(n, edges):
    in_degree = [0] * n
    graph = defaultdict(list)
    for u, v in edges:
        graph[u].append(v)
        in_degree[v] += 1
    return graph, in_degree

graph, ind = compute_in_degree(4, [(0,1),(0,2),(1,3),(2,3)])
print('In-degrees:', ind)  # [0, 1, 1, 2]

कान के एल्गोरिदम का कार्यान्वयन

0 इन-डिग्री वाले सभी नोडों को कतार में डालें। प्रत्येक नोड को संसाधित करें: उसे परिणाम में जोड़ें, फिर उसके प्रत्येक पड़ोसी की इन-डिग्री घटाएँ और 0 होने पर उसे कतार में डालें। यदि परिणाम सूची में ग्राफ से कम नोड हैं, तो कोई चक्र मौजूद है — कुछ नोडों को कभी कतार से निकाला नहीं जा सका।

from collections import deque, defaultdict

def kahn_topological_sort(n, edges):
    graph = defaultdict(list)
    in_degree = [0] * n
    for u, v in edges:
        graph[u].append(v)
        in_degree[v] += 1
    
    queue = deque(i for i in range(n) if in_degree[i] == 0)
    order = []
    
    while queue:
        node = queue.popleft()
        order.append(node)
        for nxt in graph[node]:
            in_degree[nxt] -= 1
            if in_degree[nxt] == 0:
                queue.append(nxt)
    
    if len(order) == n:
        return order   # valid topological sort
    return []          # cycle detected

print(kahn_topological_sort(4, [(0,1),(0,2),(1,3),(2,3)]))

कान के एल्गोरिदम से चक्र पहचान

कान का एल्गोरिदम बिना अतिरिक्त लागत के चक्र पहचान प्रदान करता है: यदि len(order) < n, तो कुछ नोड कभी कतार में नहीं जोड़े गए, क्योंकि उनकी इन-डिग्री कभी 0 नहीं हुई — वे किसी चक्र का हिस्सा हैं। यह रंग-चिह्नित देखे गए नोडों की सारणी बनाए रखने से अधिक सरल है। चक्र मौजूद होने का संकेत देने के लिए खाली सूची लौटाएँ।

# Cyclic graph: 0->1->2->0
edges_cycle = [(0,1),(1,2),(2,0)]
result = kahn_topological_sort(3, edges_cycle)
print(result)  # [] (cycle detected)

# Acyclic graph
edges_dag = [(0,1),(1,2)]
result = kahn_topological_sort(3, edges_dag)
print(result)  # [0, 1, 2]

समय और स्थान की जटिलता

कान का एल्गोरिदम प्रत्येक नोड को एक बार (एक बार कतार से निकालकर) और प्रत्येक किनारे को एक बार (एक बार इन-डिग्री घटाकर) संसाधित करता है। समय जटिलता: O(V + E)। स्थान: आसन्नता सूची और इन-डिग्री सारणी के लिए O(V + E), तथा कतार के लिए अतिरिक्त O(V)। यह सर्वोत्तम है — मान्य क्रम बनाने के लिए कम-से-कम सभी नोडों और किनारों को पढ़ना आवश्यक है।

शब्दकोशीय रूप से सबसे छोटा टोपोलॉजिकल क्रम

कतार के बजाय न्यूनतम-हीप के साथ कान का एल्गोरिदम शब्दकोशीय रूप से सबसे छोटा टोपोलॉजिकल क्रम उत्पन्न करता है। deque को heapq से बदलें: (node) डालें और हमेशा उपलब्ध सबसे छोटे नोड को पहले संसाधित करें। इससे सभी संभावित टोपोलॉजिकल क्रमों में शब्दकोशीय रूप से सबसे छोटा मान्य क्रम सुनिश्चित होता है।

import heapq
from collections import defaultdict

def kahn_lex_order(n, edges):
    graph = defaultdict(list)
    in_degree = [0] * n
    for u, v in edges:
        graph[u].append(v)
        in_degree[v] += 1
    
    heap = [i for i in range(n) if in_degree[i] == 0]
    heapq.heapify(heap)
    order = []
    
    while heap:
        node = heapq.heappop(heap)
        order.append(node)
        for nxt in graph[node]:
            in_degree[nxt] -= 1
            if in_degree[nxt] == 0:
                heapq.heappush(heap, nxt)
    
    return order if len(order) == n else []

print(kahn_lex_order(6, [(5,2),(5,0),(4,0),(4,1),(2,3),(3,1)]))

अनुप्रयोग: पाठ्यक्रम योजना I

पाठ्यक्रम योजना (LeetCode 207): n पाठ्यक्रमों और पूर्वापेक्षाओं को देखते हुए, क्या आप सभी पाठ्यक्रम पूरे कर सकते हैं? पूर्वापेक्षाओं को दिशित किनारों के रूप में दर्शाएँ और जाँचें कि मान्य टोपोलॉजिकल क्रम मौजूद है या नहीं (अर्थात कोई चक्र नहीं है)। यदि कान का एल्गोरिदम n लंबाई का क्रम बनाता है, तो True लौटाएँ; चक्र मिलने पर False लौटाएँ।

from collections import deque, defaultdict

def canFinish(numCourses, prerequisites):
    graph = defaultdict(list)
    in_degree = [0] * numCourses
    for a, b in prerequisites:   # b must be taken before a
        graph[b].append(a)
        in_degree[a] += 1
    
    queue = deque(i for i in range(numCourses) if in_degree[i] == 0)
    count = 0
    while queue:
        node = queue.popleft()
        count += 1
        for nxt in graph[node]:
            in_degree[nxt] -= 1
            if in_degree[nxt] == 0:
                queue.append(nxt)
    
    return count == numCourses

print(canFinish(2, [[1,0]]))       # True
print(canFinish(2, [[1,0],[0,1]])) # False (cycle)

अनुप्रयोग: पाठ्यक्रम योजना II

पाठ्यक्रम योजना II (LeetCode 210): पाठ्यक्रम लेने का वास्तविक क्रम लौटाएँ। पिछली समस्या जैसा ही करें, लेकिन बूलियन के बजाय order सूची लौटाएँ। यदि कोई चक्र मौजूद हो, तो खाली सूची लौटाएँ। इसमें कान के एल्गोरिदम के परिणाम को सीधे उत्तर के रूप में उपयोग किया जाता है।

from collections import deque, defaultdict

def findOrder(numCourses, prerequisites):
    graph = defaultdict(list)
    in_degree = [0] * numCourses
    for a, b in prerequisites:
        graph[b].append(a)
        in_degree[a] += 1
    
    queue = deque(i for i in range(numCourses) if in_degree[i] == 0)
    order = []
    while queue:
        node = queue.popleft()
        order.append(node)
        for nxt in graph[node]:
            in_degree[nxt] -= 1
            if in_degree[nxt] == 0:
                queue.append(nxt)
    
    return order if len(order) == numCourses else []

print(findOrder(4, [[1,0],[2,0],[3,1],[3,2]]))

समानांतर कार्य निर्धारण

एक अधिक उन्नत उपयोग: निर्भरताओं वाले कार्यों को देखते हुए, यह ज्ञात करें कि यदि बिना निर्भरता वाले कार्य समानांतर चल सकते हों, तो आवश्यक न्यूनतम 'दौर' कितने होंगे। कान के एल्गोरिदम को BFS के स्तर-दर-स्तर क्रम जैसा चलाएँ: 0 इन-डिग्री वाले सभी नोडों को कतार में डालें, वर्तमान कतार को एक पूरे दौर के रूप में संसाधित करें, फिर नई उपलब्ध हुई प्रविष्टियों को अगले दौर के लिए कतार में डालें। दौरों की गिनती करें।

from collections import deque, defaultdict

def min_rounds(n, edges):
    graph = defaultdict(list)
    in_degree = [0] * n
    for u, v in edges:
        graph[u].append(v)
        in_degree[v] += 1
    
    queue = deque(i for i in range(n) if in_degree[i] == 0)
    rounds = 0
    while queue:
        rounds += 1
        for _ in range(len(queue)):  # process current level
            node = queue.popleft()
            for nxt in graph[node]:
                in_degree[nxt] -= 1
                if in_degree[nxt] == 0:
                    queue.append(nxt)
    return rounds

print(min_rounds(4, [(0,2),(1,2),(2,3)]))  # 3

DAG पर टोपोलॉजिकल क्रमण और DP

टोपोलॉजिकल क्रमण DAG पर गतिशील प्रोग्रामिंग संभव बनाता है: नोडों को टोपोलॉजिकल क्रम में संसाधित करें और dp[v] निकालते समय, सभी पूर्ववर्ती नोडों के dp[u] मान पहले ही अंतिम हो चुके होते हैं। यह टोपोलॉजिकल क्रमण और DP को उन समस्याओं के लिए जोड़ता है जिनमें DAG में सबसे लंबा पथ, सभी नोडों तक पहुँचने की न्यूनतम लागत या निर्भरता-श्रृंखला से अधिकतम लाभ निकालना शामिल है। यह क्रम सुनिश्चित करता है कि प्रत्येक नोड का DP मान उसकी सभी निर्भरताएँ संसाधित होने के बाद ठीक एक बार निकाला जाए।

from collections import deque, defaultdict

def longest_path_dag(V, edges):
    graph = defaultdict(list)
    in_degree = [0] * V
    for u, v, w in edges:
        graph[u].append((v, w))
        in_degree[v] += 1
    queue = deque(i for i in range(V) if in_degree[i] == 0)
    dp = [0] * V
    while queue:
        u = queue.popleft()
        for v, w in graph[u]:
            dp[v] = max(dp[v], dp[u] + w)
            in_degree[v] -= 1
            if in_degree[v] == 0: queue.append(v)
    return max(dp)

print(longest_path_dag(4, [(0,1,3),(0,2,2),(1,3,4),(2,3,1)]))  # 7

त्वरित जाँच

इस पाठ में सिखाई गई डेटा संरचनाएँ और एल्गोरिदम — कोडिंग साक्षात्कार की तैयारी से जुड़ी अवधारणाओं की अपनी समझ जाँचें।

पाठ का पुनरावलोकन

इस पाठ में आपने सीखा: कान का एल्गोरिदम BFS के साथ 0 इन-डिग्री वाले नोडों को बार-बार हटाकर टोपोलॉजिकल क्रमण निकालता है, चक्र पहचान बिना अतिरिक्त लागत के होती है — यदि len(order) < n हो, तो कोई चक्र मौजूद है, और कतार को न्यूनतम-हीप से बदलने पर शब्दकोशीय रूप से सबसे छोटा टोपोलॉजिकल क्रम मिलता है। आगे हम कान के एल्गोरिदम के विकल्प के रूप में DFS-आधारित पोस्ट-ऑर्डर टोपोलॉजिकल क्रमण का अध्ययन करेंगे।

शुरुआत निःशुल्क

एआई शिक्षक के साथ Python सीखें — निःशुल्क

अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।

पाठ्यक्रम
30
पाठ
120

अक्सर पूछे जाने वाले प्रश्न

क्या “Kahn का एल्गोरिदम: BFS टोपोलॉजिकल सॉर्ट” पाठ निःशुल्क है?

हाँ — DSA Interview Prep अध्ययन पथ के 3 तक कोई भी पाठ, जिसमें “Kahn का एल्गोरिदम: BFS टोपोलॉजिकल सॉर्ट” भी शामिल है, यहाँ वेब पर पूरा पढ़ना निःशुल्क है। इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ इंटरैक्टिव अभ्यास भी उपलब्ध कराता है। DSA Interview Prep पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

“Kahn का एल्गोरिदम: BFS टोपोलॉजिकल सॉर्ट” में मैं क्या सीखूँगा?

सभी नोडों की इन-डिग्री निकालिए, शून्य इन-डिग्री वाले नोडों को कतार में डालिए और चक्रों का पता लगाते हुए टोपोलॉजिकल क्रम बनाने के लिए कतार को संसाधित कीजिए। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ DSA Interview Prep का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।

क्या DSA Interview Prep शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?

पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर DSA Interview Prep शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 1वाँ पाठ है।

“Kahn का एल्गोरिदम: BFS टोपोलॉजिकल सॉर्ट” पाठ पूरा करने में कितना समय लगता है?

CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।

क्या मैं इस DSA Interview Prep पाठ में कोड लिख और चला सकता हूँ?

हाँ। हर DSA Interview Prep पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।

इस पाठ्यक्रम के सभी पाठ

  1. Kahn का एल्गोरिदम: BFS टोपोलॉजिकल सॉर्ट
  2. DFS पोस्ट-ऑर्डर टोपोलॉजिकल सॉर्ट
  3. Course Schedule I और II
  4. Kosaraju से दृढ़ता से जुड़े घटक
← DSA Interview Prep पर वापस जाएँ