Depth First Search (DFS) marks all the vertices of a graph as visited. So for making DFS useful, some additional information can also be stored. For instance, the order in which the vertices are visited while running DFS.
Pre-visit and Post-visit numbers are the extra information that can be stored while running a DFS on a graph and which turns out to be really useful. Pre-visit number tells the time at which the node gets into the recursion stack and Post-visit number tells the time at which the node comes out from recursion stack of DFS.
Example:

The numbers written in brackets denote [Pre-visit number, Post-visit number].
Pre and Post numbers are widely used in graph algorithms. For example, they can be used to find out whether a particular node lies in the sub-tree of another node.
To find whether u lies in the sub-tree of v or not we just compare the pre and post number of u and v. If pre[u] > pre[v] and post[u] < post[v] then u lies in the sub-tree of v otherwise not. You can see above example for more clarification.
Pre-visit and Post-visit numbers can be found by simple DFS. We will take two arrays one for storing pre numbers and one for post numbers and by taking a variable that will keep track of the time. The implementation of the same is given below:
Implementation:
#include <bits/stdc++.h>
using namespace std;
// Variable to keep track of time
int Time = 1;
// Function to perform DFS starting from node u
void dfs(int u, vector<vector<int>> aList,
vector<int> &pre,
vector<int> &post,
vector<int> &vis)
{
// Storing the pre number whenever
// the node comes into recursion stack
pre[u] = Time;
// Increment time
Time++;
vis[u] = 1;
for(int v : aList[u])
{
if (vis[v] == 0)
dfs(v, aList, pre, post, vis);
}
// Storing the post number whenever
// the node goes out of recursion stack
post[u] = Time;
Time++;
}
// Driver Code
int main()
{
// Number of nodes in graph
int n = 6;
// Adjacency list
vector<vector<int>> aList(n + 1);
vector<int> pre(n + 1);
vector<int> post(n + 1);
// Visited array
vector<int> vis(n + 1);
// Edges
aList[1].push_back(2);
aList[2].push_back(1);
aList[2].push_back(4);
aList[4].push_back(2);
aList[1].push_back(3);
aList[3].push_back(1);
aList[3].push_back(4);
aList[4].push_back(3);
aList[3].push_back(5);
aList[5].push_back(3);
aList[5].push_back(6);
aList[6].push_back(5);
// DFS starting at Node 1
dfs(1, aList, pre, post, vis);
// Number of nodes in graph
for(int i = 1; i <= n; i++)
cout << "Node " << i << " Pre number "
<< pre[i] << " Post number "
<< post[i] << endl;
return 0;
}
// This code is contributed by divyesh072019
import java.util.*;
public class GFG {
// Variable to keep track of time
static int time = 1;
// Function to perform DFS starting from node u
static void dfs(int u, ArrayList<ArrayList<Integer> > aList,
int pre[], int post[], int vis[])
{
// Storing the pre number whenever
// the node comes into recursion stack
pre[u] = time;
// Increment time
time++;
vis[u] = 1;
for (int v : aList.get(u)) {
if (vis[v] == 0)
dfs(v, aList, pre, post, vis);
}
// Storing the post number whenever
// the node goes out of recursion stack
post[u] = time;
time++;
}
// Driver code
public static void main(String args[])
{
// Number of nodes in graph
int n = 6;
// Adjacency list
ArrayList<ArrayList<Integer> > aList
= new ArrayList<ArrayList<Integer> >(n + 1);
for (int i = 1; i <= n; i++) {
ArrayList<Integer> list = new ArrayList<>();
aList.add(list);
}
aList.add(new ArrayList<Integer>());
int pre[] = new int[n + 1];
int post[] = new int[n + 1];
// Visited array
int vis[] = new int[n + 1];
// Edges
aList.get(1).add(2);
aList.get(2).add(1);
aList.get(2).add(4);
aList.get(4).add(2);
aList.get(1).add(3);
aList.get(3).add(1);
aList.get(3).add(4);
aList.get(4).add(3);
aList.get(3).add(5);
aList.get(5).add(3);
aList.get(5).add(6);
aList.get(6).add(5);
// DFS starting at Node 1
dfs(1, aList, pre, post, vis);
// Number of nodes in graph
for (int i = 1; i <= n; i++)
System.out.println("Node " + i + " Pre number "
+ pre[i] + " Post number " + post[i]);
}
}
# Variable to keep track of time
time = 1
# Function to perform DFS starting
# from node u
def dfs(u, aList, pre, post, vis):
global time
# Storing the pre number whenever
# the node comes into recursion stack
pre[u] = time
# Increment time
time += 1
vis[u] = 1
for v in aList[u]:
if (vis[v] == 0):
dfs(v, aList, pre, post, vis)
# Storing the post number whenever
# the node goes out of recursion stack
post[u] = time
time += 1
# Driver code
if __name__=='__main__':
# Number of nodes in graph
n = 6
# Adjacency list
aList = [[] for i in range(n + 1)]
pre = [0 for i in range(n + 1)]
post = [0 for i in range(n + 1)]
# Visited array
vis = [0 for i in range(n + 1)]
# Edges
aList[1].append(2)
aList[2].append(1)
aList[2].append(4)
aList[4].append(2)
aList[1].append(3)
aList[3].append(1)
aList[3].append(4)
aList[4].append(3)
aList[3].append(5)
aList[5].append(3)
aList[5].append(6)
aList[6].append(5)
# DFS starting at Node 1
dfs(1, aList, pre, post, vis)
# Number of nodes in graph
for i in range(1, n + 1):
print("Node " + str(i) +
" Pre number " + str(pre[i]) +
" Post number " + str(post[i]))
# This code is contributed by rutvik_56
using System;
using System.Collections;
using System.Collections.Generic;
class GFG{
// Variable to keep track of time
static int time = 1;
// Function to perform DFS starting from node u
static void dfs(int u, ArrayList aList,
int []pre, int []post,
int []vis)
{
// Storing the pre number whenever
// the node comes into recursion stack
pre[u] = time;
// Increment time
time++;
vis[u] = 1;
foreach(int v in (ArrayList)aList[u])
{
if (vis[v] == 0)
dfs(v, aList, pre, post, vis);
}
// Storing the post number whenever
// the node goes out of recursion stack
post[u] = time;
time++;
}
// Driver code
public static void Main(string []args)
{
// Number of nodes in graph
int n = 6;
// Adjacency list
ArrayList aList = new ArrayList(n + 1);
for(int i = 1; i <= n; i++)
{
ArrayList list = new ArrayList();
aList.Add(list);
}
aList.Add(new ArrayList());
int []pre = new int[n + 1];
int []post = new int[n + 1];
// Visited array
int []vis = new int[n + 1];
// Edges
((ArrayList)aList[1]).Add(2);
((ArrayList)aList[2]).Add(1);
((ArrayList)aList[2]).Add(4);
((ArrayList)aList[4]).Add(2);
((ArrayList)aList[1]).Add(3);
((ArrayList)aList[3]).Add(1);
((ArrayList)aList[3]).Add(4);
((ArrayList)aList[4]).Add(3);
((ArrayList)aList[3]).Add(5);
((ArrayList)aList[5]).Add(3);
((ArrayList)aList[5]).Add(6);
((ArrayList)aList[6]).Add(5);
// DFS starting at Node 1
dfs(1, aList, pre, post, vis);
// Number of nodes in graph
for(int i = 1; i <= n; i++)
Console.WriteLine("Node " + i +
" Pre number " + pre[i] +
" Post number " + post[i]);
}
}
// This code is contributed by pratham76
<script>
// Variable to keep track of time
let time = 1;
// Function to perform DFS starting
// from node u
function dfs(u, aList, pre, post, vis)
{
// Storing the pre number whenever
// the node comes into recursion stack
pre[u] = time;
// Increment time
time += 1;
vis[u] = 1;
for(let v = 0; v < aList[u].length; v++)
{
if (vis[aList[u][v]] == 0)
dfs(aList[u][v], aList, pre, post, vis);
}
// Storing the post number whenever
// the node goes out of recursion stack
post[u] = time;
time += 1;
}
// Number of nodes in graph
let n = 6;
// Adjacency list
let aList = [];
for(let i = 0; i < (n + 1); i++)
{
aList.push([]);
}
let pre = new Array(n+1);
let post = new Array(n+1);
pre.fill(0);
post.fill(0);
// Visited array
let vis = new Array(n+1);
vis.fill(0);
// Edges
aList[1].push(2);
aList[2].push(1);
aList[2].push(4);
aList[4].push(2);
aList[1].push(3);
aList[3].push(1);
aList[3].push(4);
aList[4].push(3);
aList[3].push(5);
aList[5].push(3);
aList[5].push(6);
aList[6].push(5);
// DFS starting at Node 1
dfs(1, aList, pre, post, vis);
// Number of nodes in graph
for(let i = 1; i < n + 1; i++)
{
document.write("Node " + i +
" Pre number " + pre[i] +
" Post number " + post[i] + "</br>")
}
// This code is contributed by suresh07.
</script>
Output
Node 1 Pre number 1 Post number 12 Node 2 Pre number 2 Post number 11 Node 3 Pre number 4 Post number 9 Node 4 Pre number 3 Post number 10 Node 5 Pre number 5 Post number 8 Node 6 Pre number 6 Post number 7
Time complexity: O(V + E), where V is the number of nodes or vertices and E is the number of edges in the graph.
Auxiliary Space: O(V)