Divide and Conquer Algorithms Overview
Divide and Conquer Algorithms Overview
PART – A (2x10=20)
1 Give the general recurrence for divide and conquer algorithms
The general recurrence relation for Divide and Conquer algorithms is:
T(n) = a * T(n/b) + f(n)
Where:
• T(n) → Total time to solve a problem of size n
• a → Number of subproblems into which the problem is divided
• n/b → Size of each subproblem (problem is divided into equal parts of size n/b)
• f(n) → Time required to divide the problem and combine the results
4 Given the loop for i in range(n): sum +=i, state its time complexity in Big O notation
The loop runs n times, and each iteration performs a constant-time addition.
Time Complexity: The loop runs n times, so the time complexity is O(n).
This is linear time, since the number of operations grows proportionally with n.
5 Write a Python code snippet to access a global variable inside a function
Accessing a Global Variable Inside a Function (Python)
# Global variable
greeting = "Hello, World!"
# Function accessing the global variable
def display():
print(greeting)
display()
This works because the function is reading the global variable, not modifying it.
6 A string “((a+b)*c)” is given. Use a stack-based approach to check whether the parentheses are balanced.
State the result.
expr = "((a+b)*c)"
stack = []
for char in expr:
if char == '(':
[Link](char)
elif char == ')':
if not stack:
print("Unbalanced")
break
[Link]()
else:
print("Balanced" if not stack else "Unbalanced")
Result: The string "((a+b)*c)" is Balanced — every opening ( has a matching closing ).
7 Draw the diagram of a double-ended queue (deque) after inserting elements A, B, C at the rear and
deleting one element from the front
Deque Operation
Steps:
Insert A → rear
Insert B → rear
Insert C → rear
Delete one element → front (removes A)
PART B (5x13=65)
11 Construct an ADT for a Bank Account with the following specifications:
11 Attributes: account_number, account_holder, balance
11 Operations: deposit(amount), withdraw(amount), check_balance()
a) Build a python code to define a class BankAccount that implements the above ADT
Ensure that withdrawal does not allow negative balance(use conditional statements)
Develop two account objects, perform deposit and withdrawal operations, and display the
updated balances.
How the class implementation encapsulates the data and provides abstraction
Answers:
Python Code Implementation:
class BankAccount:
def __init__(self, account_number, account_holder, balance=0):
self.__account_number = account_number
self.__account_holder = account_holder
self.__balance = balance
def check_balance(self):
print(f"Account Balance for {self.__account_holder}: Rs.{self.__balance}")
[Link](1500)
[Link](2000)
acc1.check_balance()
[Link](500)
[Link](4000)
acc2.check_balance()
Explanation – Encapsulation and Abstraction:
• **Encapsulation**: The data attributes (account_number, account_holder, balance) are
declared as private using double underscores (__). They can only be accessed or modified
through class methods. This prevents unauthorized access.
• **Abstraction**: The internal implementation details (like how balance is updated) are
hidden from the user. The user interacts only through defined methods such as deposit(),
withdraw(), and check_balance(), without knowing the underlying logic.
Thus, the class provides both data security and simplicity through encapsulation and
abstraction.
OR
11. i. Differentiate Data types, Dat structures and Abstract Data Types (5m)
b) ii. Identify the different types of namespaces in Python. Provide a small code example to
illustrate each type (8m)
i. Difference Between Data Types, Data Structures, and Abstract Data Types
Key
Concept Definition Examples
Focus
Basic
classification
Data of data that int, float, str, Nature of
Types defines the bool data
kind of value a
variable holds
Organized
collection of
Data data that Organiza
list, dict, set,
Structur allows tion and
tuple
es efficient storage
access and
modification
Logical model
defining
Abstract Behavior
operations on
Data Stack, Queue, and
data,
Types Tree, Graph operation
independent of
(ADTs) s
implementatio
n
Analogy:
Data types = building blocks (e.g., bricks)
Data structures = how bricks are arranged (e.g., wall, house)
ADTs = blueprint of what the structure should do (e.g., open door, store items)
inner()
LEGB Rule: Python resolves names in the order: Local → Enclosing → Global → Built-in
def display_info(self):
print(f"Name: {[Link]}, ID: {[Link]}")
def display_info(self):
print(f"Name: {[Link]}, ID: {[Link]}, Grade: {[Link]}")
# Polymorphic behavior
for individual in [p, s, f]:
individual.display_info()
Output:
Name: Alex, ID: 1001
Name: Bala, ID: 1002, Grade: A+
Name: Dr. Kumar, ID: 1003, Department: Computer Science
Polymorphism: The same method display_info() behaves differently based on the object type.
class Dog(Animal):
def sound(self):
print("Woof!")
class Flyer:
def fly(self):
print("Flying")
d = Duck()
[Link]() # Swimming
[Link]() # Flying
Python uses Method Resolution Order (MRO) to resolve conflicts in multiple inheritance.
OR
12 i. Explain shallow copying and deep copying in Python
.b) ii. Given the following Python Code:
import copy
employees = [
{‘id’: 1, ‘name’:’Alice’,’projects’:[‘P1’,’P2’]};
{‘id’: 2, ‘name’:Bob,’projects’:[‘P3’]};
]
Develop Python code to create a shallow copy of the employees list and demonstrate how
modifying a nested list in the original affects the copy.
Develop Python code to create a deep copy of the employees list and demonstrate that
modifications in the original do not affect the copied list.
Shallow Copy
Creates a new object but copies references to nested objects.
Changes to nested elements in the original affect the copy.
Deep Copy
Creates a new object and recursively copies all nested objects.
Changes to the original do not affect the copy.
Original List
import copy
employees = [
{'id': 1, 'name': 'Alice', 'projects': ['P1', 'P2']},
{'id': 2, 'name': 'Bob', 'projects': ['P3']}
]
Result: Both employees and shallow_copy show 'P4' in Alice’s project list—because the nested
list is shared.
Result: Only employees shows 'P5' in Bob’s project list—deep_copy remains unchanged.
It means the algorithm will not take more than linear time for large n.
Summary Table
Exam
Notati Meani Use ple Interpretat
on ng Case Functi ion
on
Upper Worst ≤ linear
O(n) 3n + 2
bound case time
Lowe
Best ≥ linear
Ω(n) r 3n + 2
case time
bound
Aver
Tight ≈ linear
Θ(n) age 3n + 2
bound time
case
Real-Life Analogy
Imagine you're driving from Chennai to Coimbatore:
Big-O: Worst-case time (traffic, rain)
Omega: Best-case time (empty roads)
Theta: Typical time under normal conditions
OR
13 i. A warehouse wants to find the maximum quantity among n products using divide-and-
.b) conquer. Write a recursive pseudocode to solve this.
ii. ALGORITHM Q(n)
//Input: A positive integer n
If n=1 return 1
Else return Q(n-1)+2*n-1
Identify the basic operation in the algorithm. Setup the recurrence relation for the number of
times the algorithm’s basic operation is executed and solve it using back substitution.
Recurrence Relation:
Let C(n) be the number of times the basic operation is executed.
[ C(n) = C(n-1) + 1,\quad \text{with } C(1) = 0 ]
Final Answer:
[ C(n) = n - 1 ]
14 A university’s registrar office manages a singly linked list of student records. Each node stores
a) a Student’s ID(integer) and their GPA (A floating-point number). The list is kept sorted in
ascending order of student IDs.
i. Explain the concept of a “head” and a “tail” in a singly linked list
ii. Develop a C function manage_records(Node** head, int student_id, float new_gpa). This
function will perform a combined search, update and insertion operation. The function should:
Search: Traverse the list to find if a student with the given student_id already exists
Update: If the student is found, update their GPA to the new_gpa
Insertion: If the student is not found, the function must create a new node with the given ID
and GPA and insert it into the correct sorted position in the list to maintain the ascending order
of student IDs.
Explanation
Search: Traverses until it finds the student or the correct insert position.
Update: If found, updates GPA.
Insert: If not found, inserts the new node in sorted order.
Maintains ascending order of student IDs.
OR
1 i. Compare and contrast the array-based implementation and the linked list implementation of the List
4 ADT
b ii. A web browser uses a doubly linked list to store the history of visited web pages. Each node in the
) list represents a web page. How the prev and next pointers are used to implement the “Back” and
“Forward” navigation buttons. Construct a C function go_back(Node* current) that returns the prev
node and go_forward(Node* current) that returns the next node.
Summary:
Use arrays when fast indexing is needed and size is predictable.
Use linked lists when frequent insertions/deletions are required.
C Function Implementation
typedef struct Node {
char* url;
struct Node* prev;
struct Node* next;
} Node;
Usage Example:
current = go_back(current); // Navigate back
current = go_forward(current); // Navigate forward
1 A simple operating system uses a circularly linked list to distribute incoming processes to three
5 different processing cores(Core 1, Core 2, Core 3). Each node stores a process ID. The system
a distributes the processes in a round-robin fashion.
) i. Define the round-robin scheduling algorithm. Why is a circular linked list a suitable data structure to
model this algorithm?
ii. Construct a C function distribute_and_search(Node** head, int num_processes, int target_id) that
performs a round-robin distribution for num_processes to three cores. The function should traverse the
list and for each processes, assign it a core (Core1, then core 2, then Core 3 and go back to 1). After
distribution, the function must search for a specific process by its target_id and print which core it was
assigned to. You must handle the search after the distribution is complete.
iii. Provide the logic of your round-robin distribution and the search process.
// Round-robin distribution
do {
current->core_assigned = core;
core = (core % 3) + 1; // Cycle through 1 → 2 → 3 → 1
current = current->next;
count++;
} while (current != *head && count < num_processes);
OR
1 An online ticket booking system stores booking IDs in an array. As new bookings arrive, they must be
5 added, and cancellations must be handled. Apply the concept of arrays as an ADT by developing C
b functions for append(), prepend(), insert(pos, element), and delete(pos). Demonstrate their use with
) step by step explanation and code in managing booking IDs when:
A new booking arrives at the end
A VIP booking must be added at the beginning
A booking is inserted at a given slot and
A cancelled booking must be removed
typedef struct {
int data[MAX];
int size;
} BookingArray;
return 0;
}
Output
Current Bookings: 101 102
Current Bookings: 999 101 102
Current Bookings: 999 888 101 102
Current Bookings: 999 888 102
PART C
16 a) A scientific calculator evaluates complex infix expressions with operators +-*/^
and multiple nested parenthesis.
It uses array-based stacks for infix-to-postfix conversion and another stack for
postfix evaluation.
Expression: ((3+5)*2^(3-1))/(4-2)
i. Evaluate the use of two stacks (operator & operand) versus other approaches
ii. Construct a C program for infix-to-postfix conversion and postfix evaluation,
including error checks for mismatched parentheses and overflow
iii. Simulate step-by-step stack operations showing intermediate postfix and
operand stack states
Expression: ((3+5)*2^(3-1))/(4-2)
Key Features:
Handles + - * / ^ operators
Supports nested parentheses
Includes error checks for:
o Mismatched parentheses
o Stack overflow
C Code Snippet (Simplified)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <string.h>
#define MAX 100
char op_stack[MAX];
int top_op = -1;
double val_stack[MAX];
int top_val = -1;
char pop_op() {
return (top_op >= 0) ? op_stack[top_op--] : '\0';
}
double pop_val() {
return (top_val >= 0) ? val_stack[top_val--] : 0;
}
// Postfix Evaluation
double evaluate_postfix(const char* postfix) {
int i = 0;
while (postfix[i]) {
if (isdigit(postfix[i])) {
push_val(postfix[i] - '0');
} else if (is_operator(postfix[i])) {
double b = pop_val();
double a = pop_val();
switch (postfix[i]) {
case '+': push_val(a + b); break;
case '-': push_val(a - b); break;
case '*': push_val(a * b); break;
case '/': push_val(a / b); break;
case '^': push_val(pow(a, b)); break;
}
}
i++;
}
return pop_val();
}
Final Result: 16
OR
16 b) An emergency room in a hospital uses a priority queue to manage patients. Each
patient has:
Name (A,B,C,…)
Priority (1= highest, 3=lowest).
Patients with higher priority are always treated first. If two patients have the
same priority, they are served in arrival order (FCFS).
1. Using the above data, Perform the following operations step by step, updating
the diagram after each step:
Insertion: Add a new patient E(Priority 1).
Deletion: Remove the highest priority patient for treatment
Peek: Show which patient is next to be treated without removing them.
2. Infer the traversal operation to display all patients in the queue in order of
treatment priority.
1. Step-by-Step Operations
Insertion: Add E (Priority 1)
E is added after B (same priority, FCFS applies)
Priority 1 → [ B, E ]
Priority 2 → [ A, D ]
Priority 3 → [ C ]
Diagram After Insertion
┌────────────┐
│ Priority 1 │ → B → E
│ Priority 2 │ → A → D
│ Priority 3 │ → C
└────────────┘