## Wednesday, July 11, 2012

### Depth First Search in C++ – Algorithm and Source Code

Basic Theory
Depth – first searches are performed by diving downward into a tree as quickly as possible. It does this by always generating a child node from the most recently expanded node, then generating that child’s children, and so on until a goal is found or some cutoff depth point d is reached. If a goal is not found when a leaf node is reached or at the cutoff point, the program backtracks to the most recently expanded node and generates another of its children. This process continues until a goal is found or failure occurs.
Algorithm
An algorithm for the depth – first search is the same as that for breadth first search except in the ordering of the nodes.

1. Place the starting node s on the top of the stack.
2. If the stack is empty, return failure and stop.
3. If the element on the stack is goal node g, return success and stop. Otherwise,
4. Remove and expand the first element , and place the children at the top of the stack.
Example
Source Code
#include <iostream>
#include <ctime>
#include <malloc.h>
using namespace std;
struct node{
int info;
struct node *next;
};

class stack{
struct node *top;
public:
stack();
void push(int);
int pop();
bool isEmpty();
void display();
};

stack::stack(){
top = NULL;
}

void stack::push(int data){
node *p;
if((p=(node*)malloc(sizeof(node)))==NULL){
cout<<"Memory Exhausted";
exit(0);
}
p = new node;
p->info = data;
p->next = NULL;
if(top!=NULL){
p->next = top;
}
top = p;
}

int stack::pop(){
struct node *temp;
int value;
if(top==NULL){
cout<<"\nThe stack is Empty"<<endl;
}else{
temp = top;
top = top->next;
value = temp->info;
delete temp;
}
return value;
}

bool stack::isEmpty(){
return (top == NULL);
}

void stack::display(){
struct node *p = top;
if(top==NULL){
cout<<"\nNothing to Display\n";
}else{
cout<<"\nThe contents of Stack\n";
while(p!=NULL){
cout<<p->info<<endl;
p = p->next;
}
}
}

class Graph {
private:
int n;
int **A;
public:
Graph(int size = 2);
~Graph();
bool isConnected(int, int);
void DFS(int , int);
};

Graph::Graph(int size) {
int i, j;
if (size < 2) n = 2;
else n = size;
A = new int*[n];
for (i = 0; i < n; ++i)
A[i] = new int[n];
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
A[i][j] = 0;
}

Graph::~Graph() {
for (int i = 0; i < n; ++i)
delete [] A[i];
delete [] A;
}

bool Graph::isConnected(int x, int y) {
return (A[x-1][y-1] == 1);
}

void Graph::addEdge(int x, int y) {
A[x-1][y-1] = A[y-1][x-1] = 1;
}

void Graph::DFS(int x, int required){
stack s;
bool *visited = new bool[n+1];
int i;
for(i = 0; i <= n; i++)
visited[i] = false;
s.push(x);
visited[x] = true;
if(x == required) return;
cout << "Depth first Search starting from vertex ";
cout << x << " : " << endl;
while(!s.isEmpty()){
int k = s.pop();
if(k == required) break;
cout<<k<<" ";
for (i = n; i >= 0 ; --i)
if (isConnected(k, i) && !visited[i]) {
s.push(i);
visited[i] = true;
}
}
cout<<endl;
delete [] visited;
}

int main(){
Graph g(8);
g.DFS(1, 4);
return 0;
} 

Complexity

The depth – first search is preferred over the breadth – first when the search tree is known to have a plentiful number of goals. The time complexity of the depth-first tree search is the same as that for breadth-first, O(bd). It is less demanding in space requirements, however, since only the path form the starting node to the current node needs to be stored. Therefore, if the depth cutoff is d, the space complexity is just O(d).

1. error in line 121. should be if(k==required)

1. Error corrected ... thanking for your help

2. can i get the opengl DFS code in C

3. can i get an opengl code for DFS in C language

2. Line 123: i > 0, otherwise segfaults.

3. This code is easy to understand. But I dont know why do people prefer to use malloc() over 'new' for memory allocation.

1. If you are using C++, then i prefer to use new rather than malloc(). Many C++ programmers prefer to use new.

2. Well this is called c hangover

4. In line 26-30 why are you allocating memory twice using both malloc as well as new for node ptr ?

1. oh you are right.. the first allocation is actually not needed, it is just to check whether memory is available or not. You can check it using new also. So you can simply omit the memory allocation using malloc.

2. May be its better to comment that portion and address in comments as alternative way of memory allocation for the sake of clarity for beginners. Also in isConnected function when you do x-1 and y-1 kindly make sure that it lies within the bounds of the array size and doesn't become negative.

3. Hey, but you malloc it to test if there's enough memory, then don't free it. So what have you tested? Maybe there was enough memory but there isn't now! You could use placement new with the malloc'ed memory - but better just catch the out of memory exception from the new if it happens!

5. Hi

and performed DFS for g.DFS(1, 8);

But my program crashes.. Can you tell me why this is happening? Thanks in advance.

1. dear ur selection of egedes r not good for ur code . so kindly chang ur selection of code . thankx

6. You don't need to code an extra Stack class.There is one already in the C++ STL library though it use's a container adapter. Just include the header file .
http://www.cplusplus.com/reference/stack/stack/ <<--- Look here for details

1. You are right... I have coded from the scratch. But the use of STL library is always recomended.

7. for (i = n; i >= 0 ; --i)
if (isConnected(k, i) && !visited[i]) {
s.push(i);
visited[i] = true;
}

you are visiting every unvisited adjacent of the vertex k in order... this is breadth first , not depth first..in depth first, we go down the tree (for instance, here we would have had to recursively call dfs(i, reqd))...

8. also in the constructor itself instead of using the nested for loop to set all values to 0 cant we do it in the above for loop itself as:

for (int i = 0; i < n; i++) {
A[i] = new int[n];
// set this row to 0's
memset(A[i], 0, n);
}

9. Combination of these two lines gives a memory leak:

113 | bool *visited = new bool[n+1];
....
120 | if(x == required) return;

10. There is some mistake in concept :
for (i = n; i >= 0 ; --i)
if (isConnected(k, i) && !visited[i])
{
s.push(i);
visited[i] = true;
}
Depth first traversal will need recursion, here code is using method of Breadth first search.

11. This seems to be BFS rather than DFS.

12. Implementation using stack STL

/* Algorithm

1. Place the starting node s on the top of the stack.
2. If the stack is empty, return failure and stop.
3. If the element on the stack is goal node g, return success and stop. Otherwise,
4. Remove and expand the first element , and place the children at the top of the stack.
*/

#include
#include
#include
#include

using namespace std;

struct node
{
int info;
node *next;
};

class graph
{
private:
int n;
int **A;
public:
graph(int size = 2);
~graph();
bool isConnected(int, int);
void DFS(int , int);
};
graph :: graph(int size)
{
//int i,j;
if(size < 2) n=2;
else n=size;
A = new int* [n];
for(int i=0; i s;

bool *vis = new bool[n+1];
for(int i=0; i<=n; i++)
vis[i] = false;
s.push(x);
vis[x] = true;
if(x == req) return;
cout<<"Depth first Search starting from vertex";
cout<=0; --i)
if(isConnected(k, i) && !vis[i])
{
s.push(i);
vis[i] = true;
}
}
cout<<endl;
delete [] vis;
}

int main()
{
graph g(8);