📖 Scenario: You are managing tasks in a project where some tasks must be done before others. This order is important to finish the project correctly.We will use a method called Topological Sort to find the right order of tasks using a graph and a technique called Depth-First Search (DFS).
🎯 Goal: Build a Go program that uses DFS to perform a topological sort on a directed graph representing tasks and their dependencies.The program will output the tasks in the order they should be done.
📋 What You'll Learn
Create a graph using a map where keys are task names (strings) and values are slices of strings representing dependent tasks.
Create a map to track visited tasks during DFS.
Implement a DFS function that visits tasks and adds them to a stack in the correct order.
Perform topological sort by running DFS on all tasks and print the final order.
💡 Why This Matters
🌍 Real World
Topological sort is used in project management, build systems, and scheduling where tasks depend on others.
💼 Career
Understanding topological sort and DFS is important for software engineers working on compilers, task schedulers, and dependency resolution.
Progress0 / 4 steps
1
Create the graph of tasks
Create a variable called graph of type map[string][]string with these exact entries: "cook": {"eat"}, "shop": {"cook"}, "eat": {}, "clean": {"shop"}
DSA Go
Hint
Use a map with string keys and slice of strings as values to represent the graph.
2
Create the visited map and stack
Add a variable called visited of type map[string]bool initialized as an empty map, and a variable called stack of type []string initialized as an empty slice.
DSA Go
Hint
Use make(map[string]bool) to create the visited map and []string{} for the stack slice.
3
Implement DFS function
Write a function called dfs that takes parameters node string, graph map[string][]string, visited map[string]bool, and a pointer to stack []string. Inside, if node is not visited, mark it visited, call dfs recursively on all neighbors from graph[node], then append node to *stack.
DSA Go
Hint
Use recursion to visit neighbors before adding the current node to the stack.
4
Run DFS on all nodes and print topological order
In main, run dfs on every node in graph if it is not visited. After that, reverse the stack slice and print each task in order using fmt.Println. Import "fmt" at the top.
DSA Go
Hint
Remember to import fmt and print the reversed stack to get the correct order.
Practice
(1/5)
1. What is the main purpose of using DFS in Topological Sort on a directed graph?
easy
A. To visit nodes in a way that ensures dependencies come before dependents
B. To find the shortest path between two nodes
C. To detect cycles in an undirected graph
D. To count the number of connected components
Solution
Step 1: Understand DFS role in Topological Sort
DFS visits nodes deeply, ensuring all dependencies of a node are visited before the node itself.
Step 2: Relate DFS order to dependencies
By pushing nodes to a stack after visiting all neighbors, we get an order where dependencies come before dependents.
Final Answer:
To visit nodes in a way that ensures dependencies come before dependents -> Option A
Quick Check:
DFS ensures dependency order = A [OK]
Hint: DFS post-order gives correct dependency order [OK]
Common Mistakes:
Confusing DFS with BFS for topological sort
Thinking topological sort finds shortest paths
Assuming DFS detects cycles in undirected graphs here
2. Which of the following Go code snippets correctly declares a recursive DFS function for topological sort?
easy
A. func dfs(node int, graph map[int][]int, visited map[int]bool, stack *[]int) { if visited[node] { return } visited[node] = true *stack = append(*stack, node) for _, neighbor := range graph[node] { dfs(neighbor, graph, visited, stack) } }
B. func dfs(node int, graph map[int][]int, visited map[int]bool, stack []int) { if visited[node] { return } visited[node] = true for _, neighbor := range graph[node] { dfs(neighbor, graph, visited, stack) } stack = append(stack, node) }
C. func dfs(node int, graph map[int][]int, visited map[int]bool, stack *[]int) { if visited[node] { return } for _, neighbor := range graph[node] { dfs(neighbor, graph, visited, stack) } visited[node] = true *stack = append(*stack, node) }
D. func dfs(node int, graph map[int][]int, visited map[int]bool, stack *[]int) { if !visited[node] { visited[node] = true for _, neighbor := range graph[node] { dfs(neighbor, graph, visited, stack) } *stack = append(*stack, node) } }
Solution
Step 1: Check visited condition and marking
func dfs(node int, graph map[int][]int, visited map[int]bool, stack *[]int) { if !visited[node] { visited[node] = true for _, neighbor := range graph[node] { dfs(neighbor, graph, visited, stack) } *stack = append(*stack, node) } } correctly checks if node is not visited before processing and marks it visited inside the condition.
Step 2: Confirm stack append and recursion
It recursively calls dfs on neighbors and appends node to stack after visiting neighbors, using pointer to modify stack.
Final Answer:
Option D code snippet -> Option D
Quick Check:
Correct DFS recursion and stack append = D [OK]
Hint: Use pointer for stack to append in recursive DFS [OK]
Common Mistakes:
Passing stack by value causing no changes
Marking visited after recursion causing repeated visits
Appending node before visiting neighbors
3. What is the output order of nodes after performing topological sort using DFS on this graph?
Step 3: Consider DFS starting order and visited nodes
Since DFS visits 5 first, then 4, the final topological order is the reverse of the post-order stack: [4, 5, 2, 3, 1, 0]. However, the question states DFS visits nodes in ascending order starting from 5, then 4. The actual post-order stack is [0,1,3,2,5,4], so reversed order is [4,5,2,3,1,0].
Final Answer:
[4, 5, 2, 3, 1, 0] -> Option B
Quick Check:
Post-order reverse = [4,5,2,3,1,0] [OK]
Hint: Reverse DFS post-order for topological sort output [OK]
Common Mistakes:
Not reversing the stack after DFS
Visiting nodes in wrong order
Ignoring already visited nodes
4. Identify the bug in this DFS-based topological sort code snippet: