// Q1. Implementation of Breadth-First-Search on an Undirected Graph with Adjacency List Representation.
#include
#include
#include
typedef enum { WHITE, GREY, BLACK } Color;
typedef struct AdjNode {
int vertex;
struct AdjNode* next;
} AdjNode;
typedef struct GraphNode {
int vertex;
Color color;
int distance;
struct GraphNode* parent;
AdjNode* head;
} GraphNode;
typedef struct {
int V;
GraphNode* nodes;
} Graph;
typedef struct ListNode {
GraphNode* data;
struct ListNode* next;
} ListNode;
typedef struct {
ListNode *front, *rear;
} Queue;
Graph create_graph(int);
void add_edge(Graph, int, int);
void print_graph(Graph);
void delete_graph(Graph);
void enqueue(Queue*, GraphNode*);
GraphNode* dequeue(Queue*);
int empty(Queue);
void BFS(Graph, int);
int main() {
int V, E, source, destination;
printf("Enter number of vertices: ");
scanf("%d", &V);
printf("Enter number of edges: ");
scanf("%d", &E);
Graph graph = create_graph(V);
for (int i = 0; i < E; i++) {
printf("Enter the %dth edge: ", i + 1);
scanf("%d%d", &source, &destination);
add_edge(graph, source, destination);
add_edge(graph, destination, source);
}
print_graph(graph);
printf("\nEnter source vertex for BFS: ");
scanf("%d", &source);
BFS(graph, source);
delete_graph(graph);
return 0;
}
void enqueue(Queue* queue, GraphNode* node) {
ListNode* new = (ListNode*)malloc(sizeof(ListNode));
if (!new) {
printf("Memory was not allocated");
exit(0);
}
new->data = node;
new->next = NULL;
if (queue->rear) {
queue->rear->next = new;
} else {
queue->front = new;
}
queue->rear = new;
}
GraphNode* dequeue(Queue* queue) {
if (!queue->front) {
return NULL;
}
ListNode* temp = queue->front;
GraphNode* data = temp->data;
queue->front = queue->front->next;
if (!queue->front) {
queue->rear = NULL;
}
free(temp);
return data;
}
int empty(Queue queue) { return queue.front == NULL; }
Graph create_graph(int V) {
Graph graph = {V, (GraphNode*)malloc(V * sizeof(GraphNode))};
if (!graph.nodes) {
printf("Memory was not allocated");
exit(0);
}
for (int i = 0; i < V; i++) {
GraphNode node = {i, WHITE, INT32_MAX, NULL, NULL};
graph.nodes[i] = node;
}
return graph;
}
void add_edge(Graph graph, int source, int destination) {
AdjNode* node = (AdjNode*)malloc(sizeof(AdjNode));
if (!node) {
printf("Memory was not allocated");
exit(0);
}
node->vertex = source;
node->next = NULL;
node->next = graph.nodes[destination].head;
graph.nodes[destination].head = node;
}
void print_graph(Graph graph) {
printf("\nAdjacency List:\n");
for (int i = 0; i < graph.V; i++) {
printf("%d: ", i);
AdjNode* current = graph.nodes[i].head;
while (current) {
printf("-> %d ", current->vertex);
current = current->next;
}
printf("\n");
}
}
void delete_graph(Graph graph) {
int i;
AdjNode* node;
for (i = 0; i < graph.V; i++) {
while (graph.nodes[i].head) {
node = graph.nodes[i].head->next;
free(graph.nodes[i].head);
graph.nodes[i].head = node;
}
}
free(graph.nodes);
}
void BFS(Graph graph, int source) {
int i;
AdjNode* adj;
GraphNode *node, *u, *v;
Queue queue = {NULL, NULL};
graph.nodes[source].color = GREY;
graph.nodes[source].distance = 0;
enqueue(&queue, &graph.nodes[source]);
printf("\nBFS Traversal starting from vertex %d: ", source);
while (!empty(queue)) {
u = dequeue(&queue);
printf("%d ", u->vertex);
adj = u->head;
while (adj) {
v = &graph.nodes[adj->vertex];
if (v->color == WHITE) {
v->color = GREY;
v->distance = u->distance + 1;
v->parent = u;
enqueue(&queue, v);
}
adj = adj->next;
}
u->color = BLACK;
}
printf("\n\nAfter BFS:\n");
for (i = 0; i < graph.V; i++) {
node = &graph.nodes[i];
printf("Vertex %d: color=", i);
if (node->color == WHITE) {
printf("WHITE");
} else if (node->color == GREY) {
printf("GREY");
} else {
printf("BLACK");
}
printf(", distance=");
if (node->distance == INT32_MAX) {
printf("INF");
} else {
printf("%d", node->distance);
}
printf(", parent=");
if (node->parent) {
printf("%d", node->parent->vertex);
} else {
printf("NULL");
}
printf("\n");
}
}