Assignment 2 DSA
Assignment 2 DSA
For
example, calculating factorial can be done recursively or iteratively. The iterative version uses a loop
to multiply numbers from 2 to `n`, eliminating the need for multiple function calls, which saves
memory and avoids stack overflow issues.
Recursive Implementation:
#include <stdio.h>
int factorial_recursive(int n) {
if (n == 0 || n == 1) // Base case
return 1;
int main() {
return 0;
Iterative Implementation:
#include <stdio.h>
int factorial_iterative(int n) {
int result = 1;
result *= i;
return result;
int main() {
return 0;
This iterative version avoids recursion and uses a loop to compute the factorial.
Ans 2- Towers of Hanoi Problem (C Language)
The Towers of Hanoi involves moving disks between three rods, following specific rules: only one disk
can be moved at a time, and no larger disk may be placed on a smaller one. The recursive solution is
to move n-1 disks to an auxiliary rod, then move the largest disk, followed by moving the n-1 disks to
the destination.
Example
#include <stdio.h>
if (n == 1) {
return;
int main() {
return 0;
Output
1. Memory Usage:
o Recursion: Each call adds to the call stack, potentially leading to stack overflow.
2. Performance:
3. Readability:
o Iteration: Can be less intuitive for complex tasks but clearer for simple loops.
4. Usability:
Example
Fibonacci Sequence:
• Recursive:
• Iterative:
int fib(int n) { int a = 0, b = 1; for (int i = 2; i <= n; i++) { int temp = a; a = b; b = temp + b; }
return b; } // Linear time
Ans 4-
Circular Queue
A circular queue is a data structure that uses a fixed-size array in a circular fashion. It allows for
efficient use of space by connecting the end of the queue back to the beginning. When the end of
the queue is reached, new elements can be added at the front if there is available space, thus
avoiding wastage of space that occurs in a linear queue.
1. Structure:
o Linear Queue: In a linear queue, elements are added at the rear and removed from
the front, leading to potential wastage of space when elements are dequeued.
o Circular Queue: The last position is connected to the first position, making it circular.
This allows for more efficient use of space.
2. Overflow Condition:
o Linear Queue: Overflow occurs when the rear reaches the end of the array.
o Circular Queue: Overflow occurs when the next position of the rear equals the front.
3. Efficiency:
o Circular queues make better use of memory and can avoid the need for shifting
elements when dequeueing.
#include <stdio.h>
#include <stdlib.h>
#define MAX 5
typedef struct {
int items[MAX];
} CircularQueue;
void initQueue(CircularQueue* q) {
q->front = -1;
q->rear = -1;
int isFull(CircularQueue* q) {
int isEmpty(CircularQueue* q) {
}
void enqueue(CircularQueue* q, int value) {
if (isFull(q)) {
printf("Queue is full!\n");
return;
if (isEmpty(q)) {
q->items[q->rear] = value;
int dequeue(CircularQueue* q) {
if (isEmpty(q)) {
printf("Queue is empty!\n");
return -1;
if (q->front == q->rear) {
} else {
return value;
void display(CircularQueue* q) {
if (isEmpty(q)) {
printf("Queue is empty!\n");
return;
printf("Queue: ");
int i = q->front;
while (1) {
if (i == q->rear) break;
i = (i + 1) % MAX;
printf("\n");
int main() {
CircularQueue q;
initQueue(&q);
enqueue(&q, 10);
enqueue(&q, 20);
enqueue(&q, 30);
display(&q);
display(&q);
enqueue(&q, 40);
enqueue(&q, 50);
enqueue(&q, 60);
display(&q);
return 0;
}
This C program implements a circular queue with functions for initializing the queue, checking if it's
full or empty, enqueuing, dequeuing, and displaying its contents. The circular structure helps utilize
space efficiently, making it advantageous over a linear queue.
Ans 5-
A dequeue (or double-ended queue) is a linear data structure that allows insertion and deletion of
elements from both ends—front and rear. It can be considered as a combination of both stack and
queue.
Operations on Dequeue
1. Insertion:
2. Deletion:
3. Other Operations:
Example
Consider a scenario where a dequeue is used to manage tasks in a scheduler. You can add tasks to
the front or back based on priority or other criteria.
C Implementation of Dequeue
#include <stdio.h>
#include <stdlib.h>
#define MAX 5
typedef struct {
int items[MAX];
} Dequeue;
dq->front = -1;
dq->rear = -1;
if (isFull(dq)) {
printf("Dequeue is full!\n");
return;
if (isEmpty(dq)) {
dq->front = dq->rear = 0; // First element
} else {
dq->items[dq->front] = value;
if (isFull(dq)) {
printf("Dequeue is full!\n");
return;
if (isEmpty(dq)) {
} else {
dq->items[dq->rear] = value;
if (isEmpty(dq)) {
printf("Dequeue is empty!\n");
return -1;
if (dq->front == dq->rear) {
} else {
dq->front = (dq->front + 1) % MAX; // Circular increment
return value;
if (isEmpty(dq)) {
printf("Dequeue is empty!\n");
return -1;
if (dq->front == dq->rear) {
} else {
return value;
if (isEmpty(dq)) {
printf("Dequeue is empty!\n");
return;
printf("Dequeue: ");
}
int main() {
Dequeue dq;
initDequeue(&dq);
insertRear(&dq, 10);
insertRear(&dq, 20);
insertFront(&dq, 30);
display(&dq);
display(&dq);
display(&dq);
return 0;
This C program implements a dequeue with functions to insert and delete elements from both ends.
The circular structure allows for efficient space utilization, making the dequeue a versatile data
structure for various applications.
Ans 6 –
Priority Queue
A priority queue is an abstract data type similar to a regular queue but with an added feature: each
element has a priority assigned to it. Elements are served based on their priority rather than their
order in the queue. In a priority queue, higher priority elements are dequeued before lower priority
ones, regardless of their position in the queue.
Differences from Regular Queue
1. Ordering:
Regular Queue: Elements are processed in the order they are added (FIFO - First In, First Out).
Priority Queue: Elements are processed based on their priority. A higher priority element can be
served before lower priority elements, even if it was added later.
2. Implementation:
Regular Queue: Can be implemented using arrays or linked lists with straightforward enqueue and
dequeue operations.
Priority Queue: Often implemented using heaps (binary heaps), which allow for efficient priority-
based operations.
3. Operations:
Regular Queue: Basic operations are enqueue (add) and dequeue (remove).
Priority Queue: Operations include enqueue (with priority) and dequeue (removing the highest
priority element).
Tasks with higher priority (e.g., system processes) are executed before lower-priority tasks (e.g.,
background processes).
Patients are treated based on the severity of their condition rather than their arrival time. Critical
patients are prioritized over less severe cases.
3. Print Spooling:
Print jobs are prioritized based on the document type or size. Important documents (e.g., legal
papers) might be printed before regular documents.
4. Event Management:
In event-driven systems, high-priority events (like interrupts in hardware systems) are processed
before lower-priority events.
Priority queues are essential in scenarios where specific tasks need to be prioritized over others,
enhancing efficiency in processing and resource allocation in various applications.