4.
Implement BFT and DFT for given graph, when graph is represented by
a) Adjacency Matrix b) Adjacency Lists
a) Adjacency Matrix
#include <stdio.h>
#include <stdlib.h>
#define V 6 // Defines a macro V representing the number of vertices in the graph. This is used to
size arrays related to graph traversal.
// This swap function swaps the values of two integers. It is used by the heapify functions during
reordering.
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
// Function to maintain the min-heap property of a binary heap where parent ≤ children.
// Take the node at index i.
// Compare it with its children: left child (2*i + 1) and right child (2*i + 2).
// Find the smallest among parent, left, and right.
// If the smallest is not the parent, swap and recursively call minHeapify on the affected child node.
void minHeapify(int arr[], int n, int i) {
int smallest = i; // Initialize smallest as root
int left = 2 * i + 1; // Left child
int right = 2 * i + 2; // Right child
// If left child is smaller than root
if (left < n && arr[left] < arr[smallest]) {
smallest = left;
// If right child is smaller than smallest so far
if (right < n && arr[right] < arr[smallest]) {
smallest = right;
// If smallest is not root
if (smallest != i) {
swap(&arr[i], &arr[smallest]); // Swap root with smallest
minHeapify(arr, n, smallest); // Recursively heapify the affected sub-tree
// Maintain the max-heap property, where parent ≥ children.
//It’s similar to minHeapify but checks if children are greater instead of smaller
void maxHeapify(int arr[], int n, int i) {
int largest = i; // Initialize largest as root
int left = 2 * i + 1; // Left child
int right = 2 * i + 2; // Right child
// If left child is greater than root
if (left < n && arr[left] > arr[largest]) {
largest = left;
// If right child is greater than largest so far
if (right < n && arr[right] > arr[largest]) {
largest = right;
}
// If largest is not root
if (largest != i) {
swap(&arr[i], &arr[largest]); // Swap root with largest
maxHeapify(arr, n, largest); // Recursively heapify the affected sub-tree
// Function to build a min-heap from an array
// Starts from the last internal node (n/2 - 1) and calls minHeapify for all parent nodes.
void buildMinHeap(int arr[], int n) {
// Start from the last internal node and heapify each node
for (int i = n / 2 - 1; i >= 0; i--) {
minHeapify(arr, n, i);
// Function to build a max-heap from an array
void buildMaxHeap(int arr[], int n) {
for (int i = n / 2 - 1; i >= 0; i--) {
maxHeapify(arr, n, i);
// Function to delete an element from the heap
// Deletes an element from a heap by:
// 1.Replacing it with the last element.
// 2.Reducing the size of the heap (*n--).
// 3. Calling both minHeapify and maxHeapify to restore either property (though usually only one is
needed in practice depending on type of heap).
void deleteElement(int arr[], int *n, int index) {
if (index < *n) {
arr[index] = arr[(*n) - 1]; // Replace the element with the last element
(*n)--; // Reduce heap size
minHeapify(arr, *n, index); // Try to maintain min-heap property
maxHeapify(arr, *n, index); // Also try to maintain max-heap property
// Function to display the heap elements
void displayHeap(int arr[], int n) {
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
printf("\n");
// Perform Breadth-First Traversal (BFS) on a graph represented by an adjacency matrix.
// Uses a queue (queue[]) to track traversal.
//Marks visited nodes.
//Starts from the given node (start) and explores all its adjacent unvisited nodes level by level.
// Adds unvisited connected nodes to the queue and prints them as they are visited.
//visited[V]: Array to track visited nodes.
// queue[]: Array used as a queue (FIFO).
// front, rear: Queue pointers
void BFT_Matrix(int graph[V][V], int start) {
int visited[V] = {0}; // Track visited vertices
int queue[V]; // Queue for BFT
int front = 0, rear = 0;
visited[start] = 1;
queue[rear++] = start; // Enqueue the starting vertex
while (front < rear) {
int node = queue[front++]; // Dequeue vertex
printf("%d ", node);
// Check all adjacent vertices
for (int i = 0; i < V; i++) {
if (graph[node][i] && !visited[i]) {
visited[i] = 1;
queue[rear++] = i; // Enqueue unvisited adjacent
printf("\n");
// Depth-First Traversal using adjacency matrix (recursive)
//Performs Depth-First Traversal (DFS) recursively on a graph.
//Starts at start vertex.
//Marks it as visited and prints it.
//Recursively calls DFT_Matrix for all adjacent unvisited nodes.
//DFS uses recursion and explores as deep as possible before backtracking.
void DFT_Matrix(int graph[V][V], int start, int visited[]) {
printf("%d ", start);
visited[start] = 1;
// Recur for all adjacent unvisited vertices
for (int i = 0; i < V; i++) {
if (graph[start][i] && !visited[i]) {
DFT_Matrix(graph, i, visited);
int main() {
// Sample undirected graph represented by adjacency matrix
int graphMatrix[V][V] = {
{0, 1, 1, 1, 0, 0},
{1, 0, 1, 0, 1, 0},
{1, 1, 0, 1, 0, 0},
{1, 0, 1, 0, 1, 1},
{0, 1, 0, 1, 0, 1},
{0, 0, 0, 1, 1, 0}
};
int visited[V] = {0}; // Visited array for DFS
//Declares a graph using adjacency matrix. A 1 at [i][j] means there's an edge between node i and
node j.
// The graph has 6 nodes (0 to 5).
// Initializes a visited[] array for DFS.
printf("BFT using Adjacency Matrix:\n");
BFT_Matrix(graphMatrix, 0); // Call Breadth First Traversal
printf("DFT using Adjacency Matrix:\n");
DFT_Matrix(graphMatrix, 0, visited); // Call Depth First Traversal
// Performs BFT and DFT from node 0
return 0;
Expected Output:
BFT using Adjacency Matrix:
012345
DFT using Adjacency Matrix:
012345
b) Adjacency Lists:
#include <stdio.h> // Standard I/O functions like printf, scanf
#include <stdlib.h> // For malloc(), free(), and other memory-related functions
#define MAX_VERTICES 100 // Maximum number of vertices allowed in the graph
// Node Structure (Linked List Node for Adjacency List)
typedef struct Node {
int vertex; // Stores the index of the adjacent vertex
struct Node* next; // Pointer to the next node in the adjacency list
} Node;
// Graph Structure
typedef struct Graph {
int numVertices; // Total number of vertices in the graph
Node* adjLists[MAX_VERTICES]; // Array of pointers to the head nodes of adjacency lists
int visited[MAX_VERTICES]; // Array to mark visited vertices (used in BFS and DFS)
} Graph;
// Function to Create a New Node in the Adjacency List
Node* createNode(int vertex) {
Node* newNode = (Node*)malloc(sizeof(Node)); // Dynamically allocate memory for a new Node
newNode->vertex = vertex; // Set the vertex number
newNode->next = NULL; // Initialize the next pointer to NULL
return newNode; // Return pointer to the newly created node
//Function to Create a Graph
Graph* createGraph(int vertices) {
Graph* graph = (Graph*)malloc(sizeof(Graph)); // Dynamically allocate memory for the graph
graph->numVertices = vertices; // Set the number of vertices
// Initialize adjacency lists and visited[] array
for (int i = 0; i < vertices; i++) {
graph->adjLists[i] = NULL; // Initially no adjacent nodes
graph->visited[i] = 0; // Mark all vertices as not visited
return graph; // Return pointer to the newly created graph
//Function to Add an Undirected Edge Between Two Vertices
void addEdge(Graph* graph, int src, int dest) {
Node* newNode = createNode(dest); // Create a node for destination
newNode->next = graph->adjLists[src]; // Insert at the beginning of src's list
graph->adjLists[src] = newNode; // Update the head pointer
newNode = createNode(src); // Create a node for source
newNode->next = graph->adjLists[dest]; // Insert at the beginning of dest's list
graph->adjLists[dest] = newNode; // Update the head pointer
//Since the graph is undirected, an edge from src to dest and from dest to src is added.
// Breadth-First Search (BFS)
void bfs(Graph* graph, int startVertex) {
int queue[MAX_VERTICES]; // Queue for BFS
int front = 0, rear = 0; // Initialize queue pointers
graph->visited[startVertex] = 1; // Mark starting vertex as visited
queue[rear++] = startVertex; // Enqueue the start vertex
while (front != rear) { // Loop until queue is empty
int currentVertex = queue[front++]; // Dequeue a vertex
printf("%d ", currentVertex); // Print the vertex
Node* temp = graph->adjLists[currentVertex]; // Traverse adjacency list of currentVertex
while (temp) {
int adjVertex = temp->vertex; // Get the adjacent vertex
if (graph->visited[adjVertex] == 0) { // If not visited
graph->visited[adjVertex] = 1; // Mark as visited
queue[rear++] = adjVertex; // Enqueue it
temp = temp->next; // Move to next adjacent node
printf("\n"); // Newline after traversal
//Depth-First Search (DFS)
void dfs(Graph* graph, int vertex) {
graph->visited[vertex] = 1; // Mark the vertex as visited
printf("%d ", vertex); // Print the vertex
Node* temp = graph->adjLists[vertex]; // Traverse adjacency list of current vertex
while (temp) {
int adjVertex = temp->vertex; // Get the adjacent vertex
if (graph->visited[adjVertex] == 0) {// If not visited
dfs(graph, adjVertex); // Recursively call dfs
temp = temp->next; // Move to next adjacent node
int main() {
int vertices = 5; // Number of vertices in the graph
Graph* graph = createGraph(vertices); // Create the graph
// Add edges to the graph
addEdge(graph, 0, 1); // Add edge between vertex 0 and 1
addEdge(graph, 0, 2); // Add edge between vertex 0 and 2
addEdge(graph, 1, 2); // Add edge between vertex 1 and 2
addEdge(graph, 1, 3); // Add edge between vertex 1 and 3
addEdge(graph, 2, 4); // Add edge between vertex 2 and 4
printf("Breadth-First Traversal starting from vertex 0:\n");
bfs(graph, 0); // Perform BFS starting from vertex 0
// Reset visited array before DFS
for (int i = 0; i < vertices; i++) {
graph->visited[i] = 0; // Mark all vertices as not visited
printf("Depth-First Traversal starting from vertex 0:\n");
dfs(graph, 0); // Perform DFS starting from vertex 0
printf("\n"); // Newline at end of output
return 0; // Return success
OUTPUT (May vary based on insertion order in adjacency list):
Expected Output:
Breadth-First Traversal starting from vertex 0:
02143
Depth-First Traversal starting from vertex 0:
02413