Skip to content

Commit ec8a6b5

Browse files
committed
graphs | bipartite graph question added
1 parent 0508a11 commit ec8a6b5

File tree

6 files changed

+286
-1
lines changed

6 files changed

+286
-1
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,10 @@ it gets converted to i-1,j-1 or we take min or max of i,j-1 and i-1,j
187187

188188
- Most of the graph questions revolves around finding the adjacent nodes and doing operations on it. Finding adjacent nodes is easy as you can get it from the matrix easily by seeing if the value corresponding to that vertex and some i is 1 and that it has to be unvisited. So basically we either do DFS or BFS.
189189
- When path between two vertices is to be found, they need not be connected directly. There may be some vertices/ nodes in between.
190+
- Sometimes a given matrix can be assumed to be a graph with a set of different rules and DFS or BFS can be applied on it.
191+
- Check question6 grapsh to check trick on how to access all surrounding elements of a cell in matrix using
192+
two arrays
193+
- In a bipartite graph a cycle will always be of even length
190194

191195
## Advanced data
192196

@@ -443,6 +447,9 @@ In case of linked list find takes O(n) time and union also takes O(n) time and c
443447
- [Write a program to do topological sort in a graph](/graphs/question3.c)
444448
- [Find if there is a path between two vertices Vi and Vj in a directed graph](/graphs/question4.c)
445449
- [Given an undirected graph, find if it has a cycle or not](/graphs/question5.c)
450+
- [Given a 2D boolean matrix, find the number of islands](/graphs/question6.c)
451+
- [Check whether a given graph is biparite or not](/graphs/question7.c)
452+
- [Detect a cycle in a directed graph](/graphs/question8.c)
446453

447454

448455
### Pattern Matching

graphs/question5.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ int dfs(int index, int parent){
9898
if(visited[temp->data] != 1){
9999
parent = index;
100100
dfs(temp->data, parent);
101-
}else if(visited[temp->data] == 1 && temp->data != parent){
101+
}else if(temp->data != parent){
102102
return 1;
103103
}
104104
temp = temp->next;

graphs/question6.c

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
Given a 2D boolean matrix, find the number of islands
3+
4+
One island is a single element or a group of ones. Group should be traversable from 1 to another in all directions
5+
but should be contigous
6+
Eg;
7+
8+
101
9+
010
10+
101
11+
12+
forms a single island only
13+
14+
1010001
15+
1100000
16+
17+
one with 101
18+
11
19+
20+
and other with 1
21+
22+
forms two islands and so on
23+
24+
METHOD:
25+
We assume this matrix to be a graph where each cell is a node and adjacent nodes are all surrounding ones
26+
at 1 distance from it. At max a cell can have 8 adjacent nodes. There will only exist an edge between a node
27+
and its adjacent nodes if the value is 1 at the node surrounding it assumed to be the adjacent node.
28+
29+
Time complexity: O(n^2 + 8n^2) //for each cell in worst case 8 other nodes will be traversed
30+
31+
*/
32+
#include <stdio.h>
33+
#include <stdlib.h>
34+
#include <stdbool.h>
35+
36+
int rows, columns;
37+
38+
int isSafe(int arr[rows][columns], int i, int j, bool visited[rows][columns]){
39+
40+
return (i >= 0) && (i < rows) && (j >= 0) && (j < columns) && (arr[i][j] && !visited[i][j]);
41+
42+
}
43+
44+
void dfs(int arr[rows][columns], int i, int j, bool visited[rows][columns]){
45+
static int rowNbr[] = {-1,-1,-1,0,0,1,1,1};
46+
static int colNbr[] = {-1,0,1,-1,1,-1,0,1};
47+
48+
visited[i][j] = true;
49+
50+
int k;
51+
for(k=0;k<8;k++){
52+
if(isSafe(arr, i+rowNbr[k],j+colNbr[k],visited)){
53+
dfs(arr, i+rowNbr[k], j+ colNbr[k], visited);
54+
}
55+
}
56+
57+
}
58+
59+
int findIslands(int arr[rows][columns]){
60+
61+
bool visited[rows][columns];
62+
63+
int i,j;
64+
65+
int count = 0;
66+
67+
for(i=0;i<rows;i++){
68+
for(j=0;j<columns;j++){
69+
if(arr[i][j] && !visited[i][j]){
70+
dfs(arr,i,j,visited);
71+
count++;
72+
}
73+
}
74+
}
75+
76+
77+
return count;
78+
}
79+
80+
int main(){
81+
82+
int arr[][5] = {
83+
{1, 1, 0, 0, 0},
84+
{0, 1, 0, 0, 1},
85+
{1, 0, 0, 1, 1},
86+
{0, 0, 0, 0, 0},
87+
{1, 0, 1, 0, 1}
88+
};
89+
90+
91+
rows = sizeof(arr)/sizeof(arr[0]);
92+
columns = sizeof(arr[0])/sizeof(arr[0][0]);
93+
94+
printf("There are in total %d islands in the given matrix\n", findIslands(arr));
95+
96+
return 0;
97+
}
98+
99+

graphs/question7.c

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
/*
2+
Check whether a given graph is bipartite or not
3+
4+
A bipartitie graph is one whose vertices can be divided into two independent sets U and V such that every (U,V)
5+
either connects a vertex from U to V or V to U
6+
7+
Or a graph which if represented in the form of a tree, alternating levels belong to two different sets
8+
9+
METHOD:
10+
We will do a BFS
11+
1) A graph containing odd length of cycles is not bipartite.
12+
2) We can start coloring the vertex starting from any vertex. The start vertex lets say is blue, all its
13+
neighbours must be given yellow. Then all the ones with yellow its neighbours should be given blue.
14+
At any given point if an already colored vertex is colored again in an opposite color, then the graph is
15+
NOT bipartite else it is bipartite
16+
17+
Time complexity: O(E+V)
18+
19+
*/
20+
21+
#include <stdio.h>
22+
#include <stdlib.h>
23+
#include <stdbool.h>
24+
#include <math.h>
25+
#define MAX 100
26+
27+
int queue[MAX];
28+
int rear = -1, front = 0;
29+
30+
int queueElementCount = 0;
31+
32+
int visited[MAX];
33+
34+
int color[MAX];
35+
36+
struct AdjListNode{
37+
int data;
38+
struct AdjListNode *next;
39+
};
40+
41+
struct AdjList{
42+
struct AdjListNode *head;
43+
};
44+
45+
struct Graph{
46+
int vertices, edges;
47+
struct AdjList *map;
48+
} *newGraph;
49+
50+
int dequeue(){
51+
queueElementCount--;
52+
return queue[front++];
53+
}
54+
55+
void enqueue(int data){
56+
queueElementCount++;
57+
queue[++rear] = data;
58+
}
59+
60+
bool isQueueEmpty(){
61+
return queueElementCount == 0;
62+
}
63+
64+
struct AdjListNode *createNode(int data){
65+
struct AdjListNode *temp = (struct AdjListNode *)malloc(sizeof(struct AdjListNode));
66+
temp->data = data;
67+
temp->next = NULL;
68+
return temp;
69+
}
70+
71+
void addEdge(int start, int end){
72+
struct AdjListNode *newNode = createNode(end);
73+
if(newGraph->map[start].head){
74+
newNode->next = newGraph->map[start].head;
75+
newGraph->map[start].head = newNode;
76+
}else{
77+
newGraph->map[start].head = newNode;
78+
}
79+
newNode = createNode(start);
80+
if(newGraph->map[end].head){
81+
newNode->next = newGraph->map[end].head;
82+
newGraph->map[end].head = newNode;
83+
}else{
84+
newGraph->map[end].head = newNode;
85+
}
86+
}
87+
88+
void displayAdjList(){
89+
int i;
90+
91+
for(i=0;i<newGraph->vertices;i++){
92+
struct AdjListNode *temp = newGraph->map[i].head;
93+
printf("%d --> ", i);
94+
while(temp){
95+
printf("%d --> ", temp->data);
96+
temp = temp->next;
97+
}
98+
printf("\n");
99+
}
100+
}
101+
102+
void initColors(){
103+
int i;
104+
for(i=0;i<newGraph->vertices;i++){
105+
color[i] = -1;
106+
}
107+
}
108+
109+
bool isBipartite(){
110+
111+
initColors();
112+
enqueue(0);
113+
color[0] = 1;
114+
115+
while(!isQueueEmpty()){
116+
int temp = dequeue();
117+
118+
struct AdjListNode *tempVertex = newGraph->map[temp].head;
119+
120+
while(tempVertex){
121+
if(color[tempVertex->data] == -1){
122+
enqueue(tempVertex->data);
123+
}
124+
if(color[temp] == 1){
125+
if(color[tempVertex->data] != -1 && color[tempVertex->data] != 2){
126+
return false;
127+
}
128+
color[tempVertex->data] = 2;
129+
}else{
130+
if(color[tempVertex->data] != -1 && color[tempVertex->data] != 1){
131+
return false;
132+
}
133+
color[tempVertex->data] = 1;
134+
}
135+
tempVertex = tempVertex->next;
136+
}
137+
138+
}
139+
return true;
140+
141+
}
142+
143+
int main(){
144+
145+
int vertices = 5;
146+
147+
newGraph = (struct Graph *)malloc(sizeof(struct Graph));
148+
newGraph->vertices = vertices;
149+
newGraph->map = (struct AdjList *)calloc(sizeof(struct AdjList),vertices);
150+
151+
addEdge(0,2);
152+
addEdge(0,1);
153+
addEdge(2,3);
154+
addEdge(1,3);
155+
156+
displayAdjList();
157+
158+
if(isBipartite()){
159+
printf("Graph is bipartite\n");
160+
}else{
161+
printf("Graph is not bipartite\n");
162+
}
163+
164+
int i;
165+
for(i=0;i<vertices;i++){
166+
printf("%d ", color[i]);
167+
}
168+
169+
return 0;
170+
}
171+
172+

graphs/question8.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/*
2+
Detect a cycle in a directed graph
3+
4+
Will be done once back edges are done
5+
*/

nextquestions.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,6 @@ TODO:
106106
- Graph topological sort method2 and matrix implementation of topo
107107
- Write a program to detect a cycle in a graph (question5) method2
108108
- breadth and depth first traversal in a tree
109+
- Graphs question6 union and find method to be done
110+
- Graphs question8 to be done along with backedges
109111

0 commit comments

Comments
 (0)