Programs
Programs
Show the
preorder, postorder and inorder traversals for the same.
For the Binary Search Tree (BST) constructed with the values inserted in the order: 12, 8, 25, 14, 9, 6, 18, the traversals
are as follows:
• Inorder Traversal: [6, 8, 9, 12, 14, 18, 25]
• Preorder Traversal: [12, 8, 6, 9, 25, 14, 18]
• Postorder Traversal: [6, 9, 8, 18, 14, 25, 12]
QUES: What is the data structure we should use for its implementation? Write a C++ function for BFS.
Data Structure for BFS Implementation:
• Graph Representation: Breadth-First Search (BFS) is commonly implemented using an adjacency list or
an adjacency matrix to represent the graph.
• Queue: A queue is the primary data structure used to manage the exploration of nodes in BFS. It
follows the First-In-First-Out (FIFO) principle, ensuring that nodes are explored level by level.
C++ Function for BFS:
Here's a basic implementation of BFS using an adjacency list and a queue:
#include <iostream> #include <vector> #include <queue> using namespace std;
void BFS(int startVertex, const vector<vector<int>>& adjList) {
int numVertices = adjList.size();
vector<bool> visited(numVertices, false); // To track visited nodes
queue<int> q;
visited[startVertex] = true; // Start BFS from the given start vertex
q.push(startVertex);
while (!q.empty()) {
int currentVertex = q.front();
q.pop();
cout << currentVertex << " "; // Print the current vertex
for (int neighbor : adjList[currentVertex]) {
if (!visited[neighbor]) {
visited[neighbor] = true;
q.push(neighbor);
}
}
} }
int main() { int numVertices = 5; // Example graph with 5 vertices
vector<vector<int>> adjList(numVertices);
adjList[0] = {1, 2}; // Add edges to the adjacency list (Example graph)
adjList[1] = {0, 3, 4};
adjList[2] = {0};
adjList[3] = {1};
adjList[4] = {1};
int startVertex = 0;
cout << "BFS starting from vertex " << startVertex << ": ";
BFS(startVertex, adjList);
return 0; }
QUES: Write the appropriate C++ functions to implement a singly linked list following these operations:
INSERT -10, 2, 67, 14, 3, 6
DELETE -3
#include <iostream> using namespace std;
struct Node { int data; Node* next;
};
void insert(Node*& head, int value) {
Node* newNode = new Node();
newNode->data = value;
newNode->next = nullptr;
if (head == nullptr) {
head = newNode;
} else {
Node* temp = head;
while (temp->next != nullptr) {
temp = temp->next;
}
temp->next = newNode;
}
}
void deleteNode(Node*& head, int value) {
if (head == nullptr) return;
if (head->data == value) {
Node* temp = head;
head = head->next;
delete temp;
return;
}
Node* temp = head;
while (temp->next != nullptr && temp->next->data != value) {
temp = temp->next;
}
if (temp->next != nullptr) {
Node* nodeToDelete = temp->next;
temp->next = temp->next->next;
delete nodeToDelete;
}
}
void display(Node* head) {
Node* temp = head;
while (temp != nullptr) {
cout << temp->data << " -> ";
temp = temp->next;
}
cout << "nullptr" << endl;
}
int main() { Node* head = nullptr;
// Inserting values
insert(head, -10); insert(head, 2); insert(head, 67);
insert(head, 14); insert(head, 3); insert(head, 6);
cout << "Linked list after insertion: ";
display(head);
deleteNode(head, 3); // Deleting a value
cout << "Linked list after deletion of 3: ";
display(head);
return 0; }
QUES: Convert the given infix expression into postfix notation. A+(B*C-(D/E-F)*G)*H Also, evaluate the generated
postfix expression using given values. A=3, B=5, C=3, D=9, E=2, F=6, G=2, H=2.
Given infix expression: A + (B * C - (D / E - F) * G) * H
Let's convert it step by step: Operands: A, B, C, D, E, F, G, H Operators: +, *, -, /, -, *
Steps for conversion: Start scanning the expression from left to right. Push operators onto the stack after considering
their precedence and associativity. Output operands directly to the postfix expression. Apply the rules for operator
precedence and associativity.
Conversion process:
1. A → Postfix: A
2. + → Stack: +
3. ( → Stack: +(
4. B → Postfix: AB
5. * → Stack: +( *
6. C → Postfix: ABC
7. - → Stack: +( * -
8. ( → Stack: +( * -(
9. D → Postfix: ABCD
10. / → Stack: +( * -( /
11. E → Postfix: ABCDE
12. - → Stack: +( * -( -
13. F → Postfix: ABCDEF
14. ) → Stack: +( * - (pop until '(')
15. * → Stack: +( * *
16. G → Postfix: ABCDE/ F -G*
17. ) → Stack: + (pop until '(')
18. * → Stack: +*
19. H → Postfix: ABCDE/ F -G*H*+
Finally, we pop all remaining operators:Postfix Expression: ABC*DE/F-G*-H*+
Evaluating the Postfix Expression: Given values: A=3, B=5, C=3, D=9, E=2, F=6, G=2, H=2
We will evaluate the postfix expression ABC*DE/F-G*-H*+ step by step:
1. Stack: [3]
2. Stack: [3, 5]
3. Stack: [3, 5, 3] (Next is *, perform multiplication)
4. Stack: [3, 15] (5 * 3)
5. Stack: [3, 15, 9]
6. Stack: [3, 15, 9, 2] (Next is /, perform division)
7. Stack: [3, 15, 4.5] (9 / 2)
8. Stack: [3, 15, 4.5, 6] (Next is -, perform subtraction)
9. Stack: [3, 15, -1.5] (4.5 - 6)
10. Stack: [3, 15, -1.5, 2] (Next is *, perform multiplication)
11. Stack: [3, 15, -3] (-1.5 * 2)
12. Stack: [3, 18] (15 - -3)
13. Stack: [3, 18, 2] (Next is *, perform multiplication)
14. Stack: [3, 36] (18 * 2)
15. Stack: [39] (3 + 36)
Final Result: 39
QUES: Explain various graph traversal schemes and write their merits and demerits.
1. Breadth-First Search (BFS): BFS explores a graph level by level starting from a source node. It uses a queue to keep
track of nodes to visit next. Merits: Shortest Path: Finds the shortest path in an unweighted graph. Level Order: Useful
for problems requiring level-wise processing of nodes. Complete: Always explores all possible nodes reachable from the
source. Demerits: Memory Usage: Can require significant memory, especially in dense graphs. Slower for Some Tasks:
May be slower than DFS for certain graph problems.
2. Depth-First Search (DFS): DFS explores as far as possible along each branch before backtracking. It uses a stack (either
explicitly or via recursion). Merits: Memory Efficient: Uses less memory than BFS for deep graphs. Path Finding: Useful
for finding paths and connected components in a graph. Backtracking: Efficient for problems involving pathfinding and
cycle detection. Demerits: Not Shortest Path: Does not guarantee the shortest path in unweighted graphs. Stack
Overflow: Can lead to stack overflow with deep recursion or large graphs.
QUES: Differentiate between UNIX and Windows based Operating System
UNIX: Design: Multitasking and multiuser environment. File System: Hierarchical, case-sensitive (/ root directory).
Interface: Command-Line Interface (CLI) predominant; GUI available (e.g., GNOME, KDE). Security: Strong permission
model, root user. Source Code: Mostly open-source (e.g., Linux) or proprietary. Software: Managed through package
managers, mostly open-source software.
Windows: Design: Primarily single-user with multiuser capabilities. File System: Hierarchical, case-insensitive (C:\ drive).
Interface: Graphical User Interface (GUI) predominant; CLI available (e.g., Command Prompt, PowerShell).
Security: ACL-based permissions, Administrator user. Source Code: Proprietary. Software: Managed through installers
and app stores, broad range of commercial software.
Summary: UNIX: Known for robustness, security, and flexibility; used in servers and workstations. Windows: Known for
user-friendly interface and extensive commercial software; widely used in personal and business environments.
QUES: What is priority interrupt technique? Explain Daisy chaining method an its working with the help of a suitable
block diagram.
Priority Interrupt Technique is a method used in computer systems to manage multiple interrupt requests (IRQs) by
assigning priority levels to each interrupt source. This ensures that the most critical interrupts are handled before less
critical ones, improving system responsiveness and efficiency.
Daisy Chaining Method is one of the methods used to implement priority interrupts. In this method, multiple interrupt
sources are connected in series, like a chain. The interrupt requests are processed in the order of their connection.
Working of Daisy Chaining: 1. Interrupt Request: Each device sends an interrupt request signal to the next device in the
chain. 2. Propagation: The interrupt request is passed along the chain until it reaches the end. 3. Priority Handling: The
first device in the chain with an active interrupt request will take priority. 4. Service: The interrupt controller processes
the highest priority request and then passes the interrupt signal along the chain to the next device if it has a pending
request.
Block Diagram: Here’s a simplified block diagram illustrating the Daisy Chaining method:
• Devices: Device 1, Device 2, and Device 3 are interrupt sources connected in a daisy chain.
• Interrupt Requests: Each device sends its interrupt request signal to the next device in the chain.
• Interrupt Controller: Receives and processes interrupt requests, servicing the highest priority request first.
QUES: Describe how system call works. Explain the following system call:
(i) fork (ii) ioctl (iii) chmod (iv) sleep
System calls provide a way for user programs to request services from the operating system. They act as an interface
between user space and kernel space.
Steps: 1. User Request: Application makes a system call. 2. Mode Switch: The system call triggers a switch from user mode
to kernel mode. 3. Kernel Execution: The operating system executes the system call and performs the requested
operation. 4. Return: Control returns to the user application with the result.
System Calls: 1. fork: Creates a new process by duplicating the calling process. Usage: pid_t fork();
2. ioctl: Controls device-specific operations not covered by standard system calls. Usage: int ioctl(int fd, unsigned long
request, ...);
3. chmod: Changes the permissions of a file or directory. Usage: int chmod(const char *path, mode_t mode);
4. sleep: Suspends the calling process for a specified number of seconds. Usage: unsigned int sleep(unsigned int seconds);
Graph Details: The graph is undirected and has 5 vertices labeled 0 to 4. The edges are:
0 – 1, 0 – 2, 0 – 3, 1 – 2, 2 - 4
DFS Traversal: Starting from vertex 0, the DFS algorithm works by exploring as far as possible along each branch
before backtracking. The steps are:
1. Start at vertex 0: Visit 0 and push it to the stack. Stack: [0]
2. Explore the neighbors of 0: Move to vertex 1 (neighbor of 0).Visit 1 and push it to the stack. Stack: [0, 1]
3. Explore the neighbors of 1: Vertex 0 is already visited, so skip it. Move to vertex 2 (neighbor of 1).
Visit 2 and push it to the stack. Stack: [0, 1, 2]
4. Explore the neighbors of 2: Vertices 0 and 1 are already visited, so skip them. Move to vertex 4 (neighbor of 2).
Visit 4 and push it to the stack. Stack: [0, 1, 2, 4]
5. Explore the neighbors of 4: Vertex 2 is already visited, so backtrack. Stack: [0, 1, 2]
6. Backtrack to 2: All neighbors of 2 are visited, so backtrack further. Stack: [0, 1]
7. Backtrack to 1: All neighbors of 1 are visited, so backtrack further. Stack: [0]
8. Backtrack to 0: Move to vertex 3 (remaining neighbor of 0). Visit 3 and push it to the stack. Stack: [0, 3]
9. Explore the neighbors of 3: Vertex 0 is already visited, so backtrack. Stack: [0]
10.Backtrack to 0: All neighbors of 0 are visited.
DFS Order: The DFS traversal order for the given graph is: 0 → 1 → 2 → 4 → 3.
QUES: What do you meant by Time Space Tradeoff ? Explain all the 3 cases (Best, Average, Worst) w.r.t to it.
The Time-Space Tradeoff is a concept in computer science where you make a choice between optimizing for time (speed
of execution) and space (amount of memory used). In some cases, you may need to use more memory to reduce
execution time, or you might reduce memory usage at the expense of longer execution times.
Explanation of the Three Cases: Best, Average, and Worst: When analyzing algorithms, we typically consider three
different cases with respect to time complexity:
1. Best Case: The scenario where the algorithm performs the minimum number of operations. Time-Space Tradeoff: In
the best case, an algorithm might use less memory if it requires fewer operations or uses efficient data structures.
However, this is usually less significant because the focus is on optimal performance.
2. Average Case: The scenario that represents the expected number of operations an algorithm performs, averaged over
all possible inputs. Time-Space Tradeoff: The average case gives a more realistic picture of how an algorithm will
perform in practice. Here, you might need to balance between the typical execution time and space usage, making
tradeoffs depending on the expected input size and frequency.
3. Worst Case: The scenario where the algorithm performs the maximum number of operations. Time-Space Tradeoff:
In the worst case, you may need to use extra space to prevent excessive time complexity. Alternatively, reducing space
usage could lead to significantly increased execution time.
QUES: What are the advantages of linked list over arrays ? Implement Doubly Circular Linked List and insert an element
at a given position in this linked list.
Advantages of Linked Lists Over Arrays: Dynamic Size: Linked lists can grow and shrink dynamically, unlike arrays with a
fixed size. Efficient Insertions/Deletions: Insertions and deletions are more efficient as they don’t require shifting
elements. Memory Utilization: Memory is allocated as needed, avoiding wasted space.
#include <iostream> using namespace std;
struct Node { int data; Node* next; Node* prev;
};
class DoublyCircularLinkedList {
private: Node* head;
public: DoublyCircularLinkedList() : head(nullptr) {}
void insert(int data) {
Node* newNode = new Node{data, nullptr, nullptr};
if (!head) {
newNode->next = newNode;
newNode->prev = newNode;
head = newNode;
} else {
Node* last = head->prev;
newNode->next = head;
newNode->prev = last;
last->next = newNode;
head->prev = newNode;
}
}
void display() {
if (!head) return;
Node* temp = head;
do { cout << temp->data << " ";
temp = temp->next;
} while (temp != head);
cout << endl;
}
};
int main() {
DoublyCircularLinkedList list;
list.insert(10); list.insert(20); list.insert(30);
list.display(); // Output: 10 20 30
return 0;
}
QUES: Write an algorithm to evaluate a postfix expression. Execute your algorithm using the following postfix
expression as your input : a b + c d +*f ^.
Example Postfix Expression: a b + c d + * f ^
Let's break down this expression: a b + → (a + b), c d + → (c + d), * → (a + b) * (c + d), f ^ → ((a + b) * (c + d)) ^ f
Now let's evaluate this step-by-step using our algorithm: Execution of the Algorithm
1. Initialize an empty stack.
2. Scan the postfix expression:
▪ Push a onto the stack: Stack: [a]
▪ Push b onto the stack: Stack: [a, b]
▪ Encounter + (an operator): Pop b and a from the stack. Calculate a + b.
Push the result onto the stack. Stack: [a + b]
▪ Push c onto the stack: Stack: [a + b, c]
▪ Push d onto the stack: Stack: [a + b, c, d]
▪ Encounter + (an operator): Pop d and c from the stack. Calculate c + d.
Push the result onto the stack. Stack: [a + b, c + d]
▪ Encounter * (an operator): Pop c + d and a + b from the stack. Calculate (a + b) * (c + d).
Push the result onto the stack. Stack: [(a + b) * (c + d)]
▪ Push f onto the stack: Stack: [(a + b) * (c + d), f]
▪ Encounter ^ (an operator): Pop f and (a + b) * (c + d) from the stack. Calculate ((a + b) * (c + d)) ^ f.
Push the result onto the stack.Stack: [((a + b) * (c + d)) ^ f]
3. Final Result:The stack now contains the final result [((a + b) * (c + d)) ^ f].
QUES: What is a Stack ? Write an algorithm to perform push and pop operations in array.
A Stack is a linear data structure that follows the Last In, First Out (LIFO) principle. This means that the last element
added (pushed) to the stack is the first one to be removed (popped). It is analogous to a stack of plates where you can
only add or remove plates from the top of the stack.
Algorithm to Perform Push and Pop Operations Using an Array
Let’s assume we have a stack implemented using an array stack[], and a variable top to keep track of the index of the top
element in the stack.
1. Push Operation: Algorithm: Step 1: Check if the stack is full by comparing the top index with the maximum size of the
stack. If top is equal to MAX-1, then the stack is full, and the push operation cannot be performed.
Step 2: If the stack is not full:Increment the top index by 1. Insert the new element at stack[top].
Pseudocode: procedure push(stack, element)
if top == MAX-1 then
print "Stack Overflow"
else
top = top + 1
stack[top] = element
end procedure
2. Pop Operation: Algorithm: Step 1: Check if the stack is empty by checking if top is equal to -1. If top is -1, then the
stack is empty, and the pop operation cannot be performed. Step 2: If the stack is not empty: Retrieve the element at
stack[top]. Decrement the top index by 1. Return the retrieved element.
Pseudocode: procedure pop(stack)
if top == -1 then
print "Stack Underflow"
return NULL
else
element = stack[top]
top = top - 1
return element
end procedure
QUES: What is meant by binary search tree ? Consider a list of 10 elements as (A=10, 2, 3, 4, 6, 9, 10, 11, 0, 13). Explain
the implementations of binary search tree using this list.
A Binary Search Tree (BST) is a type of binary tree in which each node has at most two children. The key properties of a
BST are: 1. Left Subtree: Contains only nodes with keys less than the node’s key. 2. Right Subtree: Contains only nodes
with keys greater than the node’s key. 3. Both the left and right subtrees must also be binary search trees.
QUES: Explain /,/bin,/dev & /etc of Unix file system.
1. / (Root Directory): The top-level directory in the Unix file system hierarchy. It is the starting point of the file system
tree. Function: All other directories and files are subdirectories or files within this root directory. It provides the base
path from which all other paths are derived.
2. /bin (Binaries): Contains essential binary executables or commands that are required for basic system operations.
Function: Includes fundamental commands that are needed for the system to operate and for users to perform basic
tasks (e.g., ls, cp, mv, cat). These commands are available for use in single-user mode and are critical for system recovery
and maintenance.
3. /dev (Devices): Contains device files that represent hardware devices and system peripherals.
Function: Provides access to physical devices (e.g., disks, terminals, printers) and virtual devices (e.g., random number
generators). Device files allow software to interact with hardware devices using standard file operations. For example,
/dev/sda might represent a hard disk drive.
4. /etc (Configuration): Stores system-wide configuration files and scripts. Function: Contains configuration files that
control system and application settings (e.g., network settings, user accounts). Examples include /etc/passwd (user
account information), /etc/fstab (file system mount points), and /etc/hosts (static hostnames).
QUES: An instruction at address 021 in the basic computer has I=0, an operation code of the AND instruction and an
address part equal to 083 (all numbers are in hexadecimal). The memory word at 083 contains the operand B8F2 and
the content of AC is A937. Go over the instruction cycle and determine the contents of the following registers at the
end of the execution phase: PC, AC, DR, and IR. Make assumptions, if needed.
Given Information: Instruction Address: 021 (hexadecimal). Instruction: I=0, Operation Code: AND, Address Part: 083
(hexadecimal). Memory Content at Address 083: B8F2 (hexadecimal). Content of AC (Accumulator): A937 (hexadecimal)
Steps to Determine Register Contents:
1. Fetch the Instruction: Program Counter (PC): Initially holds the address of the instruction to be executed. Memory
Address 021 contains the instruction I=0, AND, 083. Instruction Register (IR): Loaded with the fetched instruction.
After Fetch: PC: 021 + 1 = 022 (moves to the next instruction address). IR: I=0, AND, 083
2. Decode the Instruction: Instruction: AND with address 083. Since I=0, this is a direct addressing mode instruction.
Operation: Logical AND operation.
3. Execute the Instruction: Fetch Operand: Access memory at address 083 to get the operand. Memory Content at
Address 083: B8F2. Data Register (DR): Loaded with the operand B8F2.
Perform AND Operation: AC: A937. DR: B8F2. Perform A937 AND B8F2
A937: 1010 1001 0011 0111 (binary)
B8F2: 1011 1000 1111 0010 (binary)
-----------------------------------
AND: 1010 1000 0011 0010 (binary)
Result: A832 (hexadecimal)
AC: Updated with the result A832.
4. Update the Registers: PC: Already updated to 022 during the fetch phase. AC: Updated to the result of the AND
operation, A832. DR: Contains the operand fetched from memory, B8F2. IR: Contains the instruction that was executed,
I=0, AND, 083.