Sie sind auf Seite 1von 8

EXPERIMENT 10

AIM:Code and analyze to do a depth-first search (DFS) on an undirected graph.


Implementing an application of DFS such as (i) to find the topological sort of a
directed acyclic graph, OR (ii) to find a path from source to goal in a maze.

PSEUDO CODE:
DFS-iterative (G, s): //Where G is graph and s is source vertex
let S be stack
S.push( s ) //Inserting s in stack
mark s as visited.
while ( S is not empty):
//Pop a vertex from stack to visit next
v = S.top( )
S.pop( )
//Push all the neighbours of v in stack that are not visited
for all neighbours w of v in Graph G:
if w is not visited :
S.push( w )
mark w as visited

DFS-recursive(G, s):
mark s as visited
for all neighbours w of s in Graph G:
if w is not visited:
DFS-recursive(G, w)

PROGRAM CODE:
#include<iostream>
#include <list>
using namespace std;

class Graph
{
int V; // No. of vertices
list<int> *adj; // Pointer to an array containing adjacency lists
void DFSUtil(int v, bool visited[]); // A function used by DFS
public:
Graph(int V); // Constructor
void addEdge(int v, int w); // function to add an edge to graph
void DFS(); // prints DFS traversal of the complete graph
};

Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}

void Graph::addEdge(int v, int w)


{
adj[v].push_back(w); // Add w to vs list.
}

void Graph::DFSUtil(int v, bool visited[])


{
// Mark the current node as visited and print it
visited[v] = true;
cout << v << " ";

// Recur for all the vertices adjacent to this vertex


list<int>::iterator i;
for(i = adj[v].begin(); i != adj[v].end(); ++i)
if(!visited[*i])
DFSUtil(*i, visited);
}

// The function to do DFS traversal. It uses recursive DFSUtil()


void Graph::DFS()
{
// Mark all the vertices as not visited
bool *visited = new bool[V];
for (int i = 0; i < V; i++)
visited[i] = false;

// Call the recursive helper function to print DFS traversal


// starting from all vertices one by one
for (int i = 0; i < V; i++)
if (visited[i] == false)
DFSUtil(i, visited);
}

int main()
{
// Create a graph given in the above diagram
Graph g(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);

cout << "Following is Depth First Traversaln";


g.DFS();

return 0;
}
Run on IDE

OUTPUT:

Following is Depth First Traversal


0123

(A)Topological Sorting
3.2
Topological sorting for Directed Acyclic Graph (DAG) is a linear ordering of vertices such that
for every directed edge uv, vertex u comes before v in the ordering.Topological Sorting for a
graph is not possible if the graph is not a DAG.
For example, a topological sorting of the following graph is 5 4 2 3 1 0. There can be more
than one topological sorting for a graph. For example, another topological sorting of the
following graph is 4 5 2 3 1 0. The first vertex in topological sorting is always a vertex with in-
degree as 0 (a vertex with no in-coming edges).
PROGRAM CODE:
// A C++ program to print topological sorting of a DAG
#include<iostream>
#include <list>
#include <stack>
using namespace std;

// Class to represent a graph


class Graph
{
int V; // No. of vertices'

// Pointer to an array containing adjacency listsList


list<int> *adj;

// A function used by topologicalSort


void topologicalSortUtil(int v, bool visited[], stack<int> &Stack);
public:
Graph(int V); // Constructor

// function to add an edge to graph


void addEdge(int v, int w);

// prints a Topological Sort of the complete graph


void topologicalSort();
};

Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
}

void Graph::addEdge(int v, int w)


{
adj[v].push_back(w); // Add w to vs list.
}

// A recursive function used by topologicalSort


void Graph::topologicalSortUtil(int v, bool visited[],
stack<int> &Stack)
{
// Mark the current node as visited.
visited[v] = true;

// Recur for all the vertices adjacent to this vertex


list<int>::iterator i;
for (i = adj[v].begin(); i != adj[v].end(); ++i)
if (!visited[*i])
topologicalSortUtil(*i, visited, Stack);

// Push current vertex to stack which stores result


Stack.push(v);
}

// The function to do Topological Sort. It uses recursive


// topologicalSortUtil()
void Graph::topologicalSort()
{
stack<int> Stack;

// Mark all the vertices as not visited


bool *visited = new bool[V];
for (int i = 0; i < V; i++)
visited[i] = false;

// Call the recursive helper function to store Topological


// Sort starting from all vertices one by one
for (int i = 0; i < V; i++)
if (visited[i] == false)
topologicalSortUtil(i, visited, Stack);

// Print contents of stack


while (Stack.empty() == false)
{
cout << Stack.top() << " ";
Stack.pop();
}
}

// Driver program to test above functions


int main()
{
// Create a graph given in the above diagram
Graph g(6);
g.addEdge(5, 2);
g.addEdge(5, 0);
g.addEdge(4, 0);
g.addEdge(4, 1);
g.addEdge(2, 3);
g.addEdge(3, 1);

cout << "Following is a Topological Sort of the given graph n";


g.topologicalSort();

return 0;
}
Run on IDE

OUTPUT:
Following is a Topological Sort of the given graph
542310
(B) Backtracking (Rat in a Maze)
A Maze is given as N*N binary matrix of blocks where source block is the upper left most block
i.e., maze[0][0] and destination block is lower rightmost block i.e., maze[N-1][N-1]. A rat starts
from source and has to reach destination. The rat can move only in two directions: forward and
down.
In the maze matrix, 0 means the block is dead end and 1 means the block can be used in the path
from source to destination. Note that this is a simple version of the typical Maze problem. For
example, a more complex version can be that the rat can move in 4 directions and a more
complex version can be with limited number of moves.
PROGRAM CODE:

/* C/C++ program to solve Rat in a Maze problem using


backtracking */
#include<stdio.h>

// Maze size
#define N 4

bool solveMazeUtil(int maze[N][N], int x, int y, int sol[N][N]);

/* A utility function to print solution matrix sol[N][N] */


void printSolution(int sol[N][N])
{
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
printf(" %d ", sol[i][j]);
printf("\n");
}
}

/* A utility function to check if x,y is valid index for N*N maze */


bool isSafe(int maze[N][N], int x, int y)
{
// if (x,y outside maze) return false
if(x >= 0 && x < N && y >= 0 && y < N && maze[x][y] == 1)
return true;

return false;
}

/* This function solves the Maze problem using Backtracking. It mainly


uses solveMazeUtil() to solve the problem. It returns false if no
path is possible, otherwise return true and prints the path in the
form of 1s. Please note that there may be more than one solutions,
this function prints one of the feasible solutions.*/
bool solveMaze(int maze[N][N])
{
int sol[N][N] = { {0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
};

if(solveMazeUtil(maze, 0, 0, sol) == false)


{
printf("Solution doesn't exist");
return false;
}

printSolution(sol);
return true;
}

/* A recursive utility function to solve Maze problem */


bool solveMazeUtil(int maze[N][N], int x, int y, int sol[N][N])
{
// if (x,y is goal) return true
if(x == N-1 && y == N-1)
{
sol[x][y] = 1;
return true;
}

// Check if maze[x][y] is valid


if(isSafe(maze, x, y) == true)
{
// mark x,y as part of solution path
sol[x][y] = 1;

/* Move forward in x direction */


if (solveMazeUtil(maze, x+1, y, sol) == true)
return true;

/* If moving in x direction doesn't give solution then


Move down in y direction */
if (solveMazeUtil(maze, x, y+1, sol) == true)
return true;

/* If none of the above movements work then BACKTRACK:


unmark x,y as part of solution path */
sol[x][y] = 0;
return false;
}

return false;
}

// driver program to test above function


int main()
{
int maze[N][N] = { {1, 0, 0, 0},
{1, 1, 0, 1},
{0, 1, 0, 0},
{1, 1, 1, 1}
};

solveMaze(maze);
return 0;
}
Run on IDE

OUTPUT:
The 1 values show the path for rat
1 0 0 0
1 1 0 0
0 1 0 0
0 1 1 1

Das könnte Ihnen auch gefallen