0% found this document useful (0 votes)
5 views39 pages

Rajeev

Uploaded by

nrajeev610
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views39 pages

Rajeev

Uploaded by

nrajeev610
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 39

2023-24 QUESTION PAPER SOLUTIONS

Subject = Data structure and Algorithms


SECTION-A
Q 1(a) : What are the various asymptotic notations?
Ans . There are three types of notations;

Big O (O-notation):

 Definition: It provides an upper bound on the growth rate of a function. It describes


the worst-case scenario or the maximum time complexity.

Big Omega (Ω-notation):

 Definition: It provides a lower bound on the growth rate of a function. It describes the
best-case scenario or the minimum time complexity.

Big Theta (Θ-notation):

 Definition: It provides both an upper and a lower bound on the growth rate of a
function. It describes the tight bound on the asymptotic behavior.

Q 1(b) : Why are parenthesis needed to specify the order of


operations infix expressions but not in postfix operations?
ANS. In infix notation, operators are placed between operands, requiring parentheses to
resolve ambiguity due to operator precedence and associativity (e.g., (A + B) × C vs. A +
(B × C)).

In postfix notation (RPN), operators come after operands, inherently preserving the correct
order of operations without needing parentheses (e.g., A B + C × always means (A + B)
× C).

Thus, parentheses are essential in infix but unnecessary in postfix, making postfix easier
for computer evaluation (e.g., in stack-based computations).

Q 1(c) : How the choice of pivot element effects the


running time of quick sort algorithm?
In Quick Sort, the pivot choice affects the running time:

 Good pivot (balanced split): Leads to O(nlog⁡n)O(n \log n)O(nlogn) time, as the
array is evenly divided.
 Bad pivot (extreme split): Leads to O(n2)O(n^2)O(n2) time, as the array is poorly
divided (one subarray is nearly empty).
 Average pivot (random/median): Typically results in O(nlog⁡n)O(n \log
n)O(nlogn) time, balancing the array on average

Q(d) : What are the two different form of hashing?


ANS. The two forms of hashing are:

1. Open Addressing: Collisions are resolved by probing for an empty slot within the
table itself (e.g., linear or quadratic probing).
2. Chaining: Collisions are handled by storing multiple elements at the same index
using linked lists or other structures.

Q 1(e) : What is the significance of binary tree in huffman


algorithm?
Binary tree in Huffman algorithm:

 Optimal encoding: Shorter codes for frequent characters, longer for rare.
 Prefix-free codes: Ensures no code is a prefix of another.
 Efficient decoding: Traversal from root to leaf to decode characters.
 Optimal compression: Builds a tree based on character frequencies.

Q 1(f) : What is the number of edges in a regular graph of


degree d and n vertices?

In a regular graph of degree d and n vertices, each vertex has exactly d edges. To find the
total number of edges:

1. Total degree of the graph: Since each of the n vertices has degree d, the total degree
of the graph is n×d.
2. Number of edges: Since each edge is counted twice (once at each endpoint), the total
number of edges E is

E = (n*d)/2

So, the number of edges in a regular graph of degree d and n vertices is (n*d)/2.
Q(e ).Write the algorithm to obtain the connected components of
the graph?

Function FindConnectedComponents(graph, V):

Initialize visited[V] = {False}

Initialize components = []

For v = 0 to V-1:

If visited[v] is False:

Initialize component = []

Call DFS(v, graph, visited, component)

Add component to components

Return components

Function DFS(v, graph, visited, component):

Mark visited[v] = True

Add v to component

For each neighbor u of v:

If visited[u] is False:

Call DFS(u, graph, visited, component)

4. Example Execution

Graph Representation (Adjacency List)

0 -- 1 3 -- 4

| |2 5
Adjacency List:

0 -> 1, 2

1 -> 0

2 -> 0

3 -> 4, 5

4 -> 3

5 -> 3

Step-by-Step Execution:

 Start DFS from 0 → {0, 1, 2} forms one component.


 Start DFS from 3 → {3, 4, 5} forms another component.
 Final Connected Components Output:

Component 1: {0, 1, 2}

Component 2: {3, 4, 5}

5. Time and Space Complexity

 Time Complexity: O(V+E) (DFS runs in linear time).


 Space Complexity: O(V)(for storing visited nodes).

SECTION – B
Q 2(a) : Write a Pseudo code that will concatenate two linked
lists. Function should have two parameters, pointers to the
beginning of the lists and the function should link second list at
the end of the first list.
Function concatenateLists(list1, list2):

// list1 is Empty
if list1 is NULL:

return list2

// list2 is Empty

if list1 is NULL:

return list1

// Traverse the first list to find the last node

current = list1

while current.next != NULL:

current = current.next

// Link the last node of the first list to the second list

current.next = list2

// Return the head of the concatenated list

return list1

Q 2(b) : Write an algorithm to convert a valid


arithmetic infix expression into any equivalent postfix
expression Trace your algorithm for following infix
expression.
A+B*C-D/F
ANS. function infixToPostfix(infix):

stack = empty stack

postfix = empty list

for each symbol in infix:

if symbol is an operand:

append symbol to postfix

else if symbol is '(': // Left parenthesis

push symbol onto stack

else if symbol is ')': // Right parenthesis

while stack is not empty and top of stack is not '(':

pop from stack and append to postfix

pop '(' from stack

else if symbol is an operator (+, -, *, /):

while stack is not empty and precedence(top of stack) >= precedence(symbol):

pop from stack and append to postfix

push symbol onto stack

while stack is not empty:

pop from stack and append to postfix

return postfix

Q 2© : What are the disadvantages of linear probing in hashing?


Discuss how quadratic probing can be used to solve some of
these problems?
Disadvantages of Linear Probing in Hashing:

1. Primary Clustering: Linear probing causes consecutive occupied slots, making


subsequent insertions and lookups slower.
2. Poor Cache Utilization: Linear probing creates inefficient memory access patterns,
leading to lower cache performance.
3. Load Factor Sensitivity: As the load factor increases, performance degrades quickly
due to clustering.
4. Complex Deletion: Deleting an element is tricky and can break the chain of probes
for other elements.

Quadratic Probing as a Solution:

1. Reduces Clustering: Quadratic probing scatters probes more evenly, reducing


primary clustering.
2. Improved Performance at Higher Load Factors: It can handle higher load factors
better than linear probing by reducing collisions.
3. Better Cache Utilization: Less consecutive memory access improves cache
performance.

Limitations of Quadratic Probing:

1. Secondary Clustering: Can still suffer from secondary clustering (when two keys
follow the same probe sequence).
2. Table Size Restrictions: Requires the table size to be a prime number for efficient
probing.
3. Deletion Complexity: Deletion remains complex due to breaking probe chains.

Q 2(d) : Write a c function for non recursive post order traversal.

Ans .
#include <stdio.h>
#include <stdlib.h>
// Definition for a binary tree node
struct Node {
int data;
struct Node *left, *right;
};

struct Stack {
struct Node* data;
struct Stack* next;
};

// Function to create a new tree node


struct Node* newNode(int data) {
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
node->data = data;
node->left = node->right = NULL;
return node;
}

// Function to push a node onto the stack


void push(struct Stack** top, struct Node* node) {
struct Stack* newStackNode = (struct Stack*)malloc(sizeof(struct Stack));
newStackNode->data = node;
newStackNode->next = *top;
*top = newStackNode;
}

// Function to pop a node from the stack


struct Node* pop(struct Stack** top) {
if (*top == NULL) return NULL;
struct Stack* temp = *top;
*top = (*top)->next;
struct Node* popped = temp->data;
free(temp);
return popped;
}

// Function to check if the stack is empty


int isEmpty(struct Stack* top) {
return top == NULL;
}

// Non-recursive Post-order Traversal


void postOrderTraversal(struct Node* root) {
if (root == NULL) return;
struct Stack *stack1 = NULL, *stack2 = NULL;

push(&stack1, root);

while (!isEmpty(stack1)) {
struct Node* node = pop(&stack1);
push(&stack2, node);

if (node->left)
push(&stack1, node->left);
if (node->right)
push(&stack1, node->right);
}

while (!isEmpty(stack2)) {
struct Node* node = pop(&stack2);
printf("%d ", node->data);
}
}
//main function
int main() {
struct Node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
root->right->left = newNode(6);
root->right->right = newNode(7);

printf("Post-order traversal: ");


postOrderTraversal(root);

return 0;
}

Q 2(e) : Consider the following graph and


using Dijkstra’s Algorithm find the shortest
path .
ANS .
SECTION - C
Q 3(a) : Each element of an array Data [20][50] requires 4
bytes of storage. Base address of Data is 2000. Determine
the location of Data [10][10] when the
array is stored as:
(i) Row major
(ii) Column major
ANS. Given:

 Array: Data[20][50] (20 rows, 50 columns)


 Each element requires 4 bytes.
 Base Address = 2000
 Target element: Data[10][10]

(i) Row-major order formula:

Address = BaseAddress+[(i−1)×Total Columns+(j−1)]×Element Size

= 2000+[(10−1)×50+(10−1)]×4

= 2000+[(9×50)+9]×4

= 3836

✅ Row major order (One-based Indexing) Address = 3836

(ii) Colum-major order formula:

Address = BaseAddress+[(j−1)×TotalRows+(i−1)]×Element Size

= 2000+[(10−1)×20+(10−1)]×4

= 2000+[(9×20)+9]×4

= 2756

✅ Column-major order (One-based Indexing) Address = 2756


Q 3(b) : How will you create link list representation of a
polynomial. Explain it with
the suitable example.
ANS. Linked List Representation of a Polynomial
Definition:

A polynomial is an algebraic expression consisting of variables and coefficients. A linked list


is an efficient way to represent a polynomial as it allows dynamic memory allocation and
easy manipulation of terms.

Structure of a Polynomial Node

Each node of the linked list represents a term of the polynomial and consists of:

1. Coefficient - Represents the numerical factor.


2. Exponent - Represents the power of the variable.
3. Pointer - Points to the next term in the polynomial.

C Structure for Polynomial Representation

CopyEdit

struct Node {

int coefficient;

int exponent;

struct Node* next;

};

Example: Representing Polynomial


Given Polynomial:

4x3+3x2+5x+64x^3 + 3x^2 + 5x + 64x3+3x2+5x+6

Linked List Representation:

css

CopyEdit

[4,3] → [3,2] → [5,1] → [6,0] → NULL

Each node contains coefficient & exponent, and they are linked together.

Operations on Polynomial Linked List

1.)Insertion of Terms

Insert a new term in decreasing order of exponent.

2.)Traversal (Display the Polynomial)

Print terms in the correct mathematical format.

4.)Polynomial Addition & Multiplication

Perform operations using linked list traversal.

Advantages of Using Linked List for Polynomial Representation

✅ Efficient Memory Usage: Uses only the required memory.


✅ Easy Manipulation: Terms can be inserted, deleted, or modified easily.
✅ Handles Sparse Polynomials: No need to store terms with zero coefficients.

Q 4(a) : Write an algorithm to evaluate an


arithmetic expression using stack and show
following:
how the expression 3*(5-3) will be evaluate.
ANS . Algorithm EvaluatePostfix(expression):
1. Create an empty stack.
2. For each token in expression:

a. If token is an operand (number), push it onto the stack.


b. If token is an operator:

i. Pop the top two operands from the stack.


ii. Apply the operator on the operands.
iii. Push the result back onto the stack.

3. The final value in the stack is the result of the expression.


4. Return the result.

Example: Evaluate 3 * (5 - 3)

Step 1: Convert Infix to PostfiX :

Infix: 3 * (5 - 3)

Postfix: 3 5 3 - *

Step 2: Evaluate Postfix Expression (3 5 3 - *)

Step Token Stack (Top → Bottom) Action

1. 3 3 Push 3

2. 5 5, 3 Push 5

3. 3 3, 5, 3 Push 3

4. - 2, 3 Pop (5 - 3 = 2), push 2

5. * 6 Pop (3 * 2 = 6), push 6

Final result = 6 ✅

Time Complexity Analysis


 Infix to Postfix conversion: O(n)
 Postfix evaluation using stack: O(n)
 Overall Complexity: O(n)
Q 4(b) : A double ended Queue (deque) is a linear list
in which additions may be made at either end. Obtain
a data representation mapping a deque into one
dimensional array. Write C function to add and delete
elements from either
end of deque.
Double-Ended Queue (Deque) :

A double-ended queue (deque) is a linear data structure that allows insertion and
deletion from both ends (front and rear). It can be implemented using an array or a linked
list.

Data Representation of Deque Using Array


A deque can be stored in a one-dimensional array by maintaining:

1. Front (front) - Points to the first element.


2. Rear (rear) - Points to the last element.
3. Circular nature - To efficiently utilize memory space.

Array Representation

vbnet

CopyEdit

Index: 0 1 2 3 4 (SIZE = 5)

Deque: | 10 | 20 | 30 | 40 | 50 |

front → 0 (points to 10)

rear → 4 (points to 50)

Types of Deque:
 Input-restricted deque: Insert at rear only, delete from both ends.
 Output-restricted deque: Delete from front only, insert at both ends.

Operations on Deque
1 Insert an element at the front

 If the deque is empty, set front = rear = 0.


 Otherwise, decrement front circularly:
 front = (front - 1 + SIZE) % SIZE;
 Store the new element at front.

2 Insert an element at the rear

 If the deque is empty, set front = rear = 0.


 Otherwise, increment rear circularly:
 rear = (rear + 1) % SIZE;
 Store the new element at rear.

3 Delete an element from the front

 If the deque is empty, return underflow.


 If front == rear, reset both to -1 (deque becomes empty).
 Otherwise, increment front circularly:
 front = (front + 1) % SIZE;

4 Delete an element from the rear

 If the deque is empty, return underflow.


 If front == rear, reset both to -1.
 Otherwise, decrement rear circularly:
 rear = (rear - 1 + SIZE) % SIZE;

C Program for Deque Using Array

#include <stdio.h>

#include <stdlib.h>

#define SIZE 5 // Maximum size of deque


// Structure to represent deque

struct Deque {

int arr[SIZE];

int front, rear;

};

// Function to initialize deque

void creationDeque(struct Deque *dq) {

dq->front = -1;

dq->rear = -1;

// Function to check if deque is full

int isFull(struct Deque *dq) {

return ((dq->rear + 1) % SIZE == dq->front);

// Function to check if deque is empty

int isEmpty(struct Deque *dq) {

return (dq->front == -1);

// Insert at front

void insertFront(struct Deque *dq, int value) {

if (isFull(dq)) {

printf("Deque is full! Cannot insert at front.\n");

return;

if (isEmpty(dq)) {

dq->front = dq->rear = 0;

} else {

dq->front = (dq->front - 1 + SIZE) % SIZE;

dq->arr[dq->front] = value;

printf("Inserted %d at front\n", value);


}

// Insert at rear

void insertRear(struct Deque *dq, int value) {

if (isFull(dq)) {

printf("Deque is full! Cannot insert at rear.\n");

return;

if (isEmpty(dq)) {

dq->front = dq->rear = 0;

} else {

dq->rear = (dq->rear + 1) % SIZE;

dq->arr[dq->rear] = value;

printf("Inserted %d at rear\n", value);

// Delete from front

void deleteFront(struct Deque *dq) {

if (isEmpty(dq)) {

printf("Deque is empty! Cannot delete from front.\n");

return;

printf("Deleted %d from front\n", dq->arr[dq->front]);

if (dq->front == dq->rear) {

dq->front = dq->rear = -1;

} else {

dq->front = (dq->front + 1) % SIZE;

// Delete from rear

void deleteRear(struct Deque *dq) {

if (isEmpty(dq)) {
printf("Deque is empty! Cannot delete from rear.\n");

return;

printf("Deleted %d from rear\n", dq->arr[dq->rear]);

if (dq->front == dq->rear) {

dq->front = dq->rear = -1;

} else {

dq->rear = (dq->rear - 1 + SIZE) % SIZE;

// Display deque elements

void display(struct Deque *dq) {

if (isEmpty(dq)) {

printf("Deque is empty!\n");

return;

printf("Deque elements: ");

int i = dq->front;

while (1) {

printf("%d ", dq->arr[i]);

if (i == dq->rear)

break;

i = (i + 1) % SIZE;

printf("\n");

//main function

int main() {

struct Deque dq;

creationDeque(&dq);
insertRear(&dq, 10);

insertRear(&dq, 20);

insertFront(&dq, 5);

insertFront(&dq, 2);

display(&dq);

deleteFront(&dq);

deleteRear(&dq);

display(&dq);

return 0;

Advantages of Deque :

✅ Efficient insertions and deletions (O(1) time complexity).


✅ Flexibility – Can be used as both a stack and queue.
✅ Circular Array Implementation – Efficient memory utilization.
✅ Used in caching, scheduling, and undo-redo mechanisms

Applications:

1. CPU scheduling
2. Cache memory management
3. Sliding window problems
4. Undo-redo operations in text editors
Q 5(a) : Write a C program for sorting 100 integer
numbers wring selection sort

procedure. Discuss the worst-case time complexity of


the algorithms.

ANS . *) C Code for Selection Sort

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define SIZE 100 // Sorting 100 integers

// Function to perform Selection Sort


void selectionSort(int arr[], int n) {
int i, j, minIndex, temp;

for (i = 0; i < n - 1; i++) {


minIndex = i; // Assume the first element is the minimum

// Find the minimum element in the remaining unsorted array


for (j = i + 1; j < n; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}

// Swap the found minimum element with the first element


if (minIndex != i) {
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}

// Function to generate 100 random numbers


void generateRandomNumbers(int arr[], int n) {
srand(time(0)); // Seed for random number generation
for (int i = 0; i < n; i++) {
arr[i] = rand() % 1000; // Random numbers between 0-999
}
}

// Function to display the array


void displayArray(int arr[], int n) {
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}

// Main function
int main() {
int arr[SIZE];

generateRandomNumbers(arr, SIZE);

printf("Unsorted Array:\n");
displayArray(arr, SIZE);

selectionSort(arr, SIZE);

printf("\nSorted Array using Selection Sort:\n");


displayArray(arr, SIZE);

return 0;
}

Example Output
Unsorted Array:

145 27 3 50 76 156 101 112 132 42 …

Sorted Array using Selection Sort:

3 27 42 50 76 104 112 132 145 156 …

Time complexity : O(n²) = O(100²) = O(10,000)

1. Algorithm:
1. Find the smallest element.
2. Swap it with the first unsorted element.
3. Repeat until the array is sorted.
2. Time Complexity:
1. Best Case: O(n²)
2. Worst Case: O(n²)
3. Average Case: O(n²)

3. Space Complexity: O(1) (In-place sorting, no extra memory required).


4. Advantages:

1. Simple and easy to implement.


2. Works well with small datasets.

5. Disadvantages:

1. Not efficient for large datasets (O(n²)).


2. Takes same time even if array is already sorted.

✅ Conclusion

 Selection Sort is a simple sorting algorithm best suited for small datasets.
 It has O(n²) time complexity, making it inefficient for large datasets.
 Alternative algorithms like Merge Sort and Quick Sort are better for larger inputs.

Q 5(b) : Write a program in C language to implement


binary search algorithm. Also discuss the average
behavior of the algorithm.

ANS . Definition: Binary search is a fast searching algorithm that works on sorted arrays
using a divide and conquer approach.

1. Algorithm Steps:
1. Find midpoint.
2. Compare the key with the mid element.
3. If not found, search left or right half.
4. Repeat until element is found or array is exhausted.
2. Time Complexity:

1. Best Case: O(1)


2. Worst Case: O(log n)
3. Average Case: O(log n)
3. Space Complexity: O(1) (No extra space needed).
4. Comparison with Linear Search:

1. Linear Search: O(n) (Slower)


2. Binary Search: O(log n) (Faster)

5. Applications:

1. Search engines (Google, Bing).


2. Database indexing (MySQL, MongoDB).
3. Spell checkers in Word processors.
4. Computer games AI (pathfinding).

✅ Conclusion
 Binary Search is one of the fastest searching algorithms with O(log n) time complexity.
 It requires sorted data and works efficiently for large datasets.
 Best choice for search operations in sorted arrays.

C Program for Binary search

#include <stdio.h>

// Function to perform Binary Search

int binarySearch(int arr[], int left, int right, int key) {

while (left <= right) {

int mid = left + (right - left) / 2; // Calculate middle index

// Check if key is at mid

if (arr[mid] == key)

return mid;

// If key is greater, ignore left half

if (arr[mid] < key)

left = mid + 1;
else

right = mid - 1;

return -1; // Key not found

// Function to display the array

void displayArray(int arr[], int n) {

for (int i = 0; i < n; i++) {

printf("%d ", arr[i]);

printf("\n");

// Main function

int main() {

int arr[] = {5, 12, 19, 23, 32, 45, 56, 78, 91}; // Sorted array

int n = sizeof(arr) / sizeof(arr[0]); // Find size of array

int key;

printf("Sorted Array: ");

displayArray(arr, n);

printf("\nEnter the number to search: ");

scanf("%d", &key);

int result = binarySearch(arr, 0, n - 1, key);

if (result != -1)

printf("\nElement %d found at index %d\n", key, result);

else
printf("\nElement %d not found in the array\n", key);

return 0;

Q 6(a) : If E and I denotes the external and internal


path length of a binary tree having n internal nodes
then show that E = I + 2n.
ANS. Derivation of the Relation: E = I + 2n

1. Definition of External and Internal Path Length

 Internal Path Length (I):


The sum of the depths of all internal nodes in the binary tree.
 External Path Length (E):
The sum of the depths of all external nodes (leaves and null pointers) in the binary tree.

2. Understanding the Concept

For a binary tree with nnn internal nodes, it has n-1 external nodes. This is derived from
the fact that in a full binary tree, the number of external nodes is one more than the number
of internal nodes.

Each internal node contributes 1 extra depth to its children, causing a shift in path length
between internal and external nodes.

3. Derivation of E = I + 2n

Let’s consider how the path length changes when moving from internal nodes to external
nodes.

1. Each internal node contributes to the external path length:

o Each internal node has two children (either internal or external).


o Each step from an internal node to its child increases the depth of the external node
by 1.
o Since there are nnn internal nodes, they collectively contribute an additional 2n
steps to the external path length.

2. Total External Path Length:

E = I + 2n
This equation holds because every internal node adds 2 units (one per child) to the
external path length in addition to its own depth.

1.

4. Example to Illustrate

Consider the following binary tree:

/ \

B C

/ \ / \

D E F G

 Internal Nodes: {A, B, C} → n = 3n


 External Nodes (Leaves): {D, E, F, G} → n + 1 = 4

Calculating path lengths:

Internal Path Length I:

o Depth of A = 0
o Depth of B, C = 1
o I=0+1+1=2

External Path Length E:

o Depth of D, E, F, G = 2
o E=2+2+2+2=8

Verifying : E = I + 2n

8=2+2X3

=2+6

8= 8

✅ Correct!
Q6(b) : Suppose character a,b,c,d,e,f probabilties
has 0.07 ,0.09 , 0.12 ,0.22 , 0.23 , 0.27 respectively.
Find tne optional huffman code and draw huffman
tree . What is the average code of length?
Compute the Average Code Length

Using the formula:


L = ∑Pi×Li

where:

 Pi​ is the probability of each character.


 Li​ is the length of its Huffman code.

L = (0.07 X 4) + (0.09 X 4) + (0.12 X 3) + (0.22 X 2) + (0.23 X 2) + (0.27 X 2)

= 0.28 + 0.36 + 0.36 + 0.44 + 0.46 + 0.54

= 2.44

Average Code Length: 2.44 bits per symbol

Q 7(a) : Find the minimum spanning tree using


Prim's algorithm for the graph shown below : -
Q 7(b) : Write a program in C language to compute

the indegree and outdegree of every vertex of a

directed graph when the graph is represented by

an adjacency matrix.

ANS.

#include <stdio.h>

#define MAX 100 // Maximum number of vertices

// Function to calculate indegree and outdegree of each vertex


void computeDegrees(int graph[MAX][MAX], int vertices) {
int indegree[MAX] = {0};
int outdegree[MAX] = {0};

// Compute outdegree and indegree


for (int i = 0; i < vertices; i++) {
for (int j = 0; j < vertices; j++) {
if (graph[i][j] == 1) {
outdegree[i]++; // Outdegree: Count outgoing edges
indegree[j]++; // Indegree: Count incoming edges
}
}
}

// Print indegree and outdegree for each vertex


printf("Vertex\tIndegree\tOutdegree\n");
for (int i = 0; i < vertices; i++) {
printf("%d\t%d\t\t%d\n", i, indegree[i], outdegree[i]);
}
}
int main() {
int vertices;
int graph[MAX][MAX];

printf("Enter the number of vertices: ");


scanf("%d", &vertices);

printf("Enter the adjacency matrix (%d x %d):\n", vertices, vertices);


for (int i = 0; i < vertices; i++) {
for (int j = 0; j < vertices; j++) {
scanf("%d", &graph[i][j]);
}
}

// Compute and display the degrees


computeDegrees(graph, vertices);

return 0;
}

Example Run:

Input:

Enter the number of vertices: 4

Enter the adjacency matrix (4 x 4):

0 1 0 1

0 0 1 0

1 0 0 0

0 1 1 0

Output:

Vertex Indegree Outdegree

0 1 2

1 2 1

2 2 1

3 1 1
This program efficiently calculates the indegree and outdegree for all vertices in O(V²) time
complexity, where V is the number of vertices.

You might also like