-
Notifications
You must be signed in to change notification settings - Fork 228
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #402 from shubhankar-shandilya-india/For-Kahn's-Al…
…gorithm kahn's algorithm #233
- Loading branch information
Showing
2 changed files
with
175 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
class Solution { | ||
public: | ||
vector<int> findOrder(int numCourses, vector<pair<int, int>>& prerequisites) { | ||
vector<set<int>> graphKahn = make_graph_Kahn(numCourses, prerequisites); | ||
return findOrder_Kahn(numCourses,prerequisites); | ||
} | ||
vector<int> findOrder_Kahn(int numCourses, vector<pair<int, int>>& prerequisites) { | ||
vector<int> L; //topological order | ||
stack<int> S; //set of node without incoming edge | ||
vector<set<int>> graphKahn = make_graph_Kahn(numCourses, prerequisites); | ||
for (int i = 0; i < graphKahn.size(); i++) | ||
if (graphKahn[i].empty()){ | ||
L.push_back(i); | ||
S.push(i); | ||
//insert -1 to mark that the node is empty and already add to L | ||
graphKahn[i].insert(-1); | ||
} | ||
while (!S.empty()){ | ||
int node = S.top(); | ||
S.pop(); | ||
// delete --edge from node to other node-- | ||
for (int i = 0; i < graphKahn.size(); i++){ | ||
graphKahn[i].erase(node); | ||
if (graphKahn[i].empty()){ | ||
L.push_back(i); | ||
S.push(i); | ||
//insert -1 to mark that the node is empty and already add to L | ||
graphKahn[i].insert(-1); | ||
} | ||
} | ||
} | ||
for (auto node : graphKahn) | ||
if (*node.begin() != -1){ | ||
vector<int> nu; | ||
return nu;} | ||
return L; | ||
} | ||
//make-graph-> node-edge | ||
vector<set<int>> make_graph(int numCourses, vector<pair<int, int>>& prerequisites){ | ||
vector<set<int>> graph(numCourses); | ||
for (auto pre : prerequisites) | ||
graph[pre.second].insert(pre.first); | ||
return graph; | ||
} | ||
//make-graph for Kahn's algorithm incomming edge for a node | ||
vector<set<int>> make_graph_Kahn(int numCourses, vector<pair<int, int>>& prerequisites){ | ||
vector<set<int>> graph(numCourses); | ||
for (auto pre : prerequisites) | ||
graph[pre.first].insert(pre.second); | ||
return graph; | ||
} | ||
|
||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
#include <iostream> | ||
#include<list> | ||
#include<queue> | ||
using namespace std; | ||
|
||
//class representing a vertex of the graph | ||
class Vertex{ | ||
public: | ||
//vertex label | ||
char name; | ||
//Adjacency List | ||
list<Vertex*> neighbors; | ||
//degree of the vertex | ||
int degree = 0; | ||
|
||
|
||
Vertex(char name){ | ||
this->name = name; | ||
} | ||
|
||
//Method to connect vertices (directed) | ||
void add_neighbor(Vertex* v){ | ||
this->neighbors.push_back(v); | ||
} | ||
}; | ||
|
||
|
||
class KahnsTopological{ | ||
public: | ||
Vertex** vertices; | ||
int n; | ||
|
||
KahnsTopological(Vertex* vertices[], int n){ | ||
this->vertices = vertices; | ||
this->n = n; | ||
} | ||
|
||
//method to initialize degree of every vertices | ||
void init_degree(){ | ||
for(int i=0; i<n; i++){ | ||
Vertex* vertex= vertices[i]; | ||
for(Vertex* nbr: vertex->neighbors){ | ||
nbr->degree += 1; | ||
} | ||
} | ||
} | ||
|
||
//method to find the topological order of the graph | ||
//using the kahn's Topological sort algorithm | ||
void sort(){ | ||
//create an empty queue | ||
queue<Vertex*> Queue; | ||
|
||
//fill queue with 0 degree vertices | ||
for(int i=0; i<n; i++){ | ||
Vertex* vertex= vertices[i]; | ||
if(vertex->degree == 0) | ||
Queue.push(vertex); | ||
} | ||
|
||
//list to store topological order | ||
list<Vertex*> order; | ||
|
||
//To store count of processed vertices | ||
int count = 0; | ||
|
||
//run the algorithm until queue is empty | ||
while(!Queue.empty()){ | ||
//dequeue an vertex from the queue | ||
//and append to the order | ||
Vertex* current_vertex = Queue.front(); | ||
Queue.pop(); | ||
order.push_back(current_vertex); | ||
|
||
//decrement the degree of the connected vertices | ||
for(Vertex* nbr: current_vertex->neighbors){ | ||
nbr->degree -= 1; | ||
|
||
//if the degree reduces to 0 | ||
//add it to the queue | ||
if(nbr->degree == 0) | ||
Queue.push(nbr); | ||
} | ||
|
||
count++; | ||
} | ||
|
||
//algorithm has finished | ||
//if the number of processed vertices is greater- | ||
//than the number of vertices in the graph, | ||
//then it means the graph has a cycle | ||
if(count > n) | ||
cout << "The graph has cycle"; | ||
else{ | ||
//output the topological order | ||
for(Vertex* v: order){ | ||
cout << v->name << " "; | ||
} | ||
} | ||
} | ||
}; | ||
|
||
|
||
int main() | ||
{ | ||
//vertices | ||
Vertex* vertices[] = {new Vertex('A'), new Vertex('B'), new Vertex('C'), new Vertex('D'), new Vertex('E'), new Vertex('F')}; | ||
|
||
//connect vertices (i.e. create graph) | ||
vertices[0]->add_neighbor(vertices[1]); //A->B | ||
vertices[0]->add_neighbor(vertices[2]); //A->C | ||
vertices[1]->add_neighbor(vertices[3]); //B->D | ||
vertices[2]->add_neighbor(vertices[3]); //C->D | ||
vertices[1]->add_neighbor(vertices[4]); //B->E | ||
vertices[2]->add_neighbor(vertices[5]); //C->F | ||
vertices[4]->add_neighbor(vertices[5]); //E->F | ||
|
||
//Driver Code | ||
KahnsTopological topological(vertices, 6); | ||
topological.init_degree(); | ||
topological.sort(); | ||
} |