Golang Program to Implement Depth First Search
In this article, we are going to learn how to use internal Golang functions like make, append, and range to implement depth first search. Depth first search is a traversal algorithm used for graph and tree data structures. It explores all the nodes of the graph recursively.
Syntax
func make ([] type, size, capacity)
The make function in go language is used to create an array/map it accepts the type of variable to be created, its size and capacity as arguments
func append(slice, element_1, element_2?, element_N) []T
The append function is used to add values to an array slice. It takes number of arguments. The first argument is the array to which we wish to add the values followed by the values to add. The function then returns the final slice of array containing all the values.
func range(variable)
The range function is used to iterate over any data type. To use this, we first have to write the range keyword followed by the data type to which we want to iterate and as a result the loop will iterate till the last element of the variable.
Using Adjacency List Representation
In this method, we will write a Golang program to implement depth first search using adjacency list representation to represent the graph. The functions DFS and DFSUtil will be used to execute the depth first search
Algorithm
Step 1 ? Import the fmt and main package in the program where fmt helps in the formatting of the input and Output and the main ensures that the program should be an executable program
Step 2 ? Create a Graph struct with vertices of type int and adjacency list representation which will be used to represent the Graph
Step 3 ? Then, create an AddEdge method with source and destination as the input and in it add edges from the source to the destination
Step 4 ? Create a method DFS with startVertex as the input. In the function initialize a visited map using make function which is a built-in function in Golang
Step 5 ? Call the method DFSUtil from the DFS with two inputs: the starting vertex and the map which is initialized
Step 6 ? In the following function, recursively visit the vertex and set the visited vertex as true once it is visited and print it on the console using Println from the fmt package where ln refers to the new line
Step 7 ? In the main the vertex values are passed in AddEdge function to create a graph by connecting the vertices to form edges
Example
The following example, demonstrates golang program to implement depth first search using adjacency list representation
package main import "fmt" type Graph struct { vertices int adjList map[int][]int } func NewGraph(vertices int) *Graph { return &Graph{ vertices: vertices, adjList: make(map[int][]int), } } func (g *Graph) AddEdge(source, dest int) { g.adjList[source] = append(g.adjList[source], dest) g.adjList[dest] = append(g.adjList[dest], source) } func (g *Graph) DFSUtil(vertex int, visited map[int]bool) { visited[vertex] = true fmt.Printf("%d ", vertex) for _, v := range g.adjList[vertex] { if !visited[v] { g.DFSUtil(v, visited) } } } func (g *Graph) DFS(startVertex int) { visited := make(map[int]bool) g.DFSUtil(startVertex, visited) } func main() { g := NewGraph(5) g.AddEdge(0, 1) g.AddEdge(0, 2) g.AddEdge(1, 3) g.AddEdge(1, 4) fmt.Println("Depth-first traversal starting from vertex 0:") g.DFS(0) }
Output
Depth-first traversal starting from vertex 0: 0 1 3 4 2
Using Adjacency Matrix Representation in Iteration
In this method, we will write a Golang program to implement depth first search using adjacency matrix representation in iteration. Here the methods DFS and DFSUtil will be used to execute Depth first search.
Algorithm
Step 1 ? Import the fmt and main package in the program where fmt helps in the formatting of the input and Output and the main ensures that the program should be an executable program
Step 2 ? Create a Graph struct with adjacency matrix representation and vertices of type int
Step 3 ? Create an AddEdge method with source and destination as parameters. In this method edges will be added from the source to destination to create a graph
Step 4 ? In this step, create a DFS method with startvertex as an input. In this function create a visited map which will be set to true if a particular vertex is visited
Step 5 ? Then, from here call DFSUtil method with vertex and visited map as parameters
Step 6 ? Visit each vertex of the graph recursively, print it and set the visited as true after the vertex is visited
Step 7 ? In the main, the AddEdge method is provided with input arguments of vertices which will be connected to get the graph
Example
The following example, show the golang program to implement depth first search using adjacency matrix representation in iteration
package main import "fmt" type Graph struct { vertices int adjMatrix [][]bool } func NewGraph(vertices int) *Graph { matrix := make([][]bool, vertices) for i := 0; i < vertices; i++ { matrix[i] = make([]bool, vertices) } return &Graph{ vertices: vertices, adjMatrix: matrix, } } func (g *Graph) AddEdge(source, dest int) { g.adjMatrix[source][dest] = true g.adjMatrix[dest][source] = true } func (g *Graph) DFSUtil(vertex int, visited []bool) { visited[vertex] = true fmt.Printf("%d ", vertex) for i := 0; i < g.vertices; i++ { if g.adjMatrix[vertex][i] && !visited[i] { g.DFSUtil(i, visited) } } } func (g *Graph) DFS(startVertex int) { visited := make([]bool, g.vertices) g.DFSUtil(startVertex, visited) } func main() { g := NewGraph(5) g.AddEdge(0, 1) g.AddEdge(0, 2) g.AddEdge(1, 3) g.AddEdge(1, 4) fmt.Println("Depth-first traversal starting from vertex 0:") g.DFS(0) }
Output
Depth-first traversal starting from vertex 0: 0 1 3 4 2
Using Recursion
In this method, we will write a Golang program to implement depth first search using recursion. The function will be called until the nodes are unvisited.
Algorithm
Step 1 ? This program imports the package main and fmt where main helps in producing executable codes and fmt helps in formatting of input and Output
Step 2 ? Create a Node struct with three fields : value which depicts the data of the nodes ,visited of type bool which determines whether the node is visited or not
Step 3 ? The last one is the edges which help in addition of edges
Step 4 ? Create a function DFS which take the node as a parameter which is the root node
Step 5 ? Check if the root node is null return
Step 6 ? Then, set the root node visited as true
Step 7 ? Print the node value on the console
Step 8 ? Iterate the node edges and check if the edge is visited or not
Step 9 ? If the edge is not visited recursively call the DFS function with the edge as parameter
Step 10 ? In the main function, set the node values and connect the nodes creating the edges
Step 11 ? Call the function DFS with the node1 as parameter
Step 12 ? The Print statement is executed using Printf function from the fmt package
Example
The following example, illustrate how to create a golang program to implement depth first search using recursion
package main import "fmt" type Node struct { value int visited bool edges []*Node } func DFS(node *Node) { if node == nil { return } node.visited = true fmt.Printf("%d ", node.value) for _, edge := range node.edges { if !edge.visited { DFS(edge) } } } func main() { node1 := &Node{value: 10} node2 := &Node{value: 20} node3 := &Node{value: 30} node4 := &Node{value: 40} node5 := &Node{value: 50} node1.edges = []*Node{node2, node3} node2.edges = []*Node{node4, node5} node3.edges = []*Node{node5} DFS(node1) }
Output
The DFS traversal is: 10 20 40 50 30
Conclusion
We compiled and executed the program of implementing depth first search using three examples. In the first example adjacency list representation and in the second example we used adjacency matrix representation and in the third example we used recursion.