Graph extended - adjacency list representation

/***
Graph implement:
1. BFS
2. DFS
3. test is cyclic
4. topological sort
5. Find a path between two node in a graph --> if node v is reachable with node w
***/

#include<iostream>
#include<list>
#include <queue>

using namespace std;

class graph {
       int V;
       list<int> *adj;
       bool cyclicUtil(int, bool*, bool*);
       void BFSUtil(bool *, queue<int> &);
       void DFSUtil(int, bool*);
       void update_degree(int, int *, queue<int> &);
       bool rareachableUtil(int, int, bool *);
public:
       graph(int);
       void addEdge(int, int);
       bool iscycle();
       bool isreachable(int, int);
       void BFS();
       void DFS();
       //only acyclic graph can do topological sort
       bool topological_sort();
};

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

void graph::addEdge(int v, int w) {
       adj[v].push_back(w);
}

bool graph::cyclicUtil(int v, bool *visited, bool *check) {

       if(check[v]) return true;

       if(!visited[v]) {
              visited[v] = true;
              check[v] = true;

              list<int>::iterator it;   
              for(it = adj[v].begin(); it != adj[v].end(); it++) {
                     if(cyclicUtil(*it, visited, check)) return true;
              }
       }
       check[v] = false;
       return false;
}

bool graph::iscycle() {
       bool *visited = new bool[V];
       bool *check = new bool[V];

       //initial bool array
       for(int i=0; i<V; i++) {
              visited[i] = false;
              check[i] = false;
       }

       for(int i=0; i<V; i++) {
              if(!visited[i] && cyclicUtil(i, visited, check)) {
                     delete [] visited;
                     delete [] check;
                     return true;
              }
       }

       delete [] visited;
       delete [] check;
       return false;
}

void graph::BFSUtil(bool *visited, queue<int> &bfs) {
       list<int> :: iterator it;
       while(!bfs.empty()) {
              int cur = bfs.front();
              for(it = adj[cur].begin(); it != adj[cur].end(); it++) {
                     if(!visited[*it]) {
                           bfs.push(*it);
                           visited[*it] = true;
                     }
              }
              cout<<cur<<" ";
              bfs.pop();
       }     
}

void graph::BFS() {
       bool *visited = new bool[V];
       for(int i = 0; i<V; i++)
              visited[i] = false;

       queue<int> bfsqueue;

//     for(int i=0; i<V; i++) {
//            if(!visited[i]) {
                     bfsqueue.push(2);
                     visited[2] = true;
                     BFSUtil(visited, bfsqueue);
//            }
//     }

       delete [] visited;
}

void graph::DFSUtil(int v, bool *visited) {
       list<int> :: iterator it;
      
       visited[v] = true;
       cout<<v<<" ";

       for (it = adj[v].begin(); it != adj[v].end(); it++)
       {
              if (!visited[*it])
                     DFSUtil(*it, visited);
       }
}

void graph::DFS() {
       bool *visited = new bool[V];
       for(int i = 0; i<V; i++) visited[i] = false;

//     for(int i = 0; i < V; i++) {
//            if (!visited[i])
                     DFSUtil(2, visited);
//     }
       delete [] visited;
}

void graph::update_degree(int v, int *degree, queue<int> &zero) {
       list<int> :: iterator it;
       for(it = adj[v].begin(); it != adj[v].end(); it++) {
              --degree[*it];
              if(degree[*it] == 0)
                     zero.push(*it);
       }
}

bool graph::topological_sort() {
       int *degree = new int[V];

       //initial degree of each node
       for(int i=0; i<V; i++)
              degree[i] = 0;

       list<int> :: iterator it;
       for(int i=0; i<V; i++) {
              for(it = adj[i].begin(); it != adj[i].end(); it++) {
                     ++degree[*it];
              }
       }

       queue<int> zero;
       for(int i = 0; i<V; i++) {
              if(degree[i] == 0) {
                     zero.push(i);
              }
       }

       if(zero.empty()) return false;

       while(!zero.empty()) {
              int cur = zero.front();
              cout<<cur<<" ";
              zero.pop();
              update_degree(cur, degree, zero);
       }

       delete [] degree;
       return true;
}

bool graph :: rareachableUtil(int v, int w, bool *visited) {
       if(v == w) return true;

       visited[v] = true;
       list<int> :: iterator it;
       for(it = adj[v].begin(); it != adj[v].end(); it++) {
              if(!visited[*it] && isreachable(*it, w)) return true;
       }
       return false;
}

bool graph :: isreachable(int v, int w) {
       bool *visited = new bool[V];
       for (int i=0; i<V; i++)
       {
              visited[i] = false;
       }

       if (rareachableUtil(v, w, visited)) {
              delete [] visited;
              return true;
       } else {
              delete [] visited;
              return false;
       }
}

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);

       if (g.iscycle())
              cout<<"There is a cycle."<<endl;
       else cout<<"No cycle"<<endl;

       g.topological_sort();
       cout<<endl;

       if (g.isreachable(5, 3))
       {
              cout<<"reachable"<<endl;
       } else cout<<"not reachable"<<endl;
       return 0;

}

Comments

Popular posts from this blog

Sudoku

Longest prefix matching - trie

Climbing Stairs