BIT201 · TU past paper
Data Structures and Algorithms 2082 question paper
The complete TU 2082 exam paper for Data Structures and Algorithms (BIT201), all 12 questions with solved model answers written to the mark scheme.
Tap a question to open its answer.
- 110 marksNumericalWhy sorting is neededHideAnswer
Why do we need sorting?Trace the Quick sort for the input {12, -9, 56, 23, 4, 8, 6, 9, 23, 21}.[2+8]
(a) Why Do We Need Sorting? Sorting arranges data in a defined order (ascending or descending). We need it because: 1. Faster searching: Sorted data enables Binary Search ($O(\log n)$) instead of linear search ($O(n)$). 2. Data organizat...
- 210 marksPrimitive data types with examplesHideAnswer
Define primitive data type with example.What are the advantages of hashing?With your own example show the hash collision and how do you handle it? Explain.[2+2+6]
Primitive Data Type, Hashing, Collision and Collision Handling
1. Primitive Data Type (2 marks)
Definition: A primitive data type is a basic, built-in data type provided directly by a programming language. It is the most fundamental type of data that cannot be broken down into simpler data types. These types are predefined by the language and have a fixed size in memory.
Examples:
Data Type Description Example Value intInteger numbers 5,-20,100floatDecimal/floating point numbers 3.14,-0.5charSingle character 'A','z'booleanTrue or false value true,falseFor example, in C/Java:
int age = 21;-- hereintis a primitive data type storing a whole number.
2. Advantages of Hashing (2 marks)
Hashing is a technique of mapping keys to positions in a hash table using a hash function.
Advantages:
-
Fast Search (O(1) average): Hashing provides constant time average-case complexity for search, insert, and delete operations, which is much faster than linear search O(n) or binary search O(log n).
-
Efficient Storage and Retrieval: Data can be stored and retrieved very efficiently using a key, making it ideal for dictionaries, databases, and caches.
-
Direct Address Mapping: The hash function directly computes the storage location, avoiding sequential scanning.
-
Useful for Large Data Sets: Even with a large number of records, hashing maintains near-constant performance.
-
Easy Implementation of Symbol Tables: Compilers use hashing to implement symbol tables efficiently.
3. Hash Collision and Collision Handling (6 marks)
What is Hash Collision?
A hash collision occurs when two or more different keys produce the same hash value (index) using the hash function, meaning they map to the same location in the hash table.
My Own Example:
Hash Function:
h(key) = key mod 7Hash Table Size = 7 (indices 0 to 6)
Keys to insert: 10, 20, 17, 24, 31
Key h(key) = key mod 7 Index 10 10 mod 7 = 3 3 20 20 mod 7 = 6 6 17 17 mod 7 = 3 3 -- COLLISION with 10! 24 24 mod 7 = 3 3 -- COLLISION again! 31 31 mod 7 = 3 3 -- COLLISION again! Keys 10, 17, 24, and 31 all hash to index 3 -- this is a hash collision.
Collision Handling Techniques
Method 1: Chaining (Open Hashing)
In chaining, each slot of the hash table holds a linked list. All keys that hash to the same index are stored in the linked list at that index.
After inserting 10, 20, 17, 24, 31 using chaining:
Index 0: NULL Index 1: NULL Index 2: NULL Index 3: [10] -> [17] -> [24] -> [31] -> NULL Index 4: NULL Index 5: NULL Index 6: [20] -> NULLAdvantages of Chaining:
- Simple to implement
- Hash table never becomes full
- Deletion is easy
Method 2: Open Addressing - Linear Probing (Closed Hashing)
In linear probing, if a collision occurs at index
i, we check the next sloti+1, theni+2, and so on until an empty slot is found.Formula:
h(key, i) = (h(key) + i) mod TableSize where i = 0, 1, 2, ... (probe number)Inserting 10, 20, 17, 24, 31 using Linear Probing (Table Size = 7):
Step Key h(key) Probe Final Index 1 10 3 i=0, slot 3 empty 3 2 20 6 i=0, slot 6 empty 6 3 17 3 i=0, slot 3 full; i=1, slot 4 empty 4 4 24 3 i=0 full, i=1 full, i=2, slot 5 empty 5 5 31 3 i=0 full, i=1 full, i=2 full, i=3, slot 6 full, i=4, slot 0 empty 0 Final Hash Table:
Index 0: 31 Index 1: NULL Index 2: NULL Index 3: 10 Index 4: 17 Index 5: 24 Index 6: 20Advantages of Linear Probing:
- No extra memory needed for pointers
- Better cache performance
Disadvantage:
- Primary clustering -- long chains of filled slots can form, slowing down operations.
Summary Table
Method Idea Handles Full Table? Chaining Linked list at each slot Yes Linear Probing Next available slot No (table can fill up) Conclusion: Hash collision is unavoidable in practice, but with proper handling techniques like chaining or open addressing the table keeps giving almost constant time access. Chaining is preferred when the number of keys is not known in advance or when deletions are frequent, while linear probing suits a table of fixed size where memory for pointers is not available. In both cases the load factor should be kept low (roughly 0.7 or less for open addressing) so that the average number of probes stays close to one.
-
- 310 marksStatic versus dynamic list structuresHideAnswer
Distinguish between static and dynamic list structure.Explain about linked list implementation of stack and queue.[2+8]
Static vs Dynamic List Structure & Linked List Implementation of Stack and Queue
(a) Static vs Dynamic List Structure
Feature Static List Structure Dynamic List Structure Memory Allocation Memory is allocated at compile time (fixed size) Memory is allocated at run time (as needed) Size Size is fixed and cannot change during execution Size can grow or shrink during execution Implementation Implemented using arrays Implemented using linked lists Memory Utilization May waste memory (if underused) or overflow (if overused) Efficient memory utilization; no wastage Insertion/Deletion Costly; requires shifting of elements Easy; only pointer adjustments needed Access Direct/random access using index Sequential access only Example int arr[100]Singly/doubly linked list
(b) Linked List Implementation of Stack and Queue
A. Linked List Implementation of Stack
A stack is a linear data structure that follows the LIFO (Last In First Out) principle. In linked list implementation, each node contains data and a pointer to the next node. The top pointer always points to the most recently inserted node.
Node Structure
struct Node { int data; struct Node* next; }; struct Node* top = NULL;[data | next] --> [data | next] --> [data | next] --> NULL ^ TOP
i. PUSH Operation (Insert at top)
Steps:
- Create a new node.
- Assign data to the new node.
- Make new node's
nextpoint to currenttop. - Update
topto the new node.
void push(int value) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); if (newNode == NULL) { printf("Stack Overflow\n"); return; } newNode->data = value; newNode->next = top; // new node points to old top top = newNode; // top updated to new node }Diagram (Push 10, 20, 30):
After Push(10): TOP -> [10 | NULL] After Push(20): TOP -> [20 | *] -> [10 | NULL] After Push(30): TOP -> [30 | *] -> [20 | *] -> [10 | NULL]
ii. POP Operation (Delete from top)
Steps:
- Check if stack is empty (top == NULL).
- Store the top node in a temporary pointer.
- Move
topto the next node. - Free the temporary node.
void pop() { if (top == NULL) { printf("Stack Underflow\n"); return; } struct Node* temp = top; printf("Popped: %d\n", temp->data); top = top->next; // move top to next node free(temp); // free old top }
iii. PEEK / Display
void peek() { if (top == NULL) printf("Stack is Empty\n"); else printf("Top element: %d\n", top->data); }
B. Linked List Implementation of Queue
A queue is a linear data structure that follows the FIFO (First In First Out) principle. In linked list implementation, two pointers are maintained:
- FRONT -- points to the first node (deletion end)
- REAR -- points to the last node (insertion end)
Node Structure
struct Node { int data; struct Node* next; }; struct Node* front = NULL; struct Node* rear = NULL;FRONT REAR | | [data|next] -> [data|next] -> [data|NULL]
i. ENQUEUE Operation (Insert at rear)
Steps:
- Create a new node.
- Assign data to the new node; set its
nextto NULL. - If queue is empty, both
frontandrearpoint to new node. - Otherwise, link the current
rear's next to new node and updaterear.
void enqueue(int value) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); if (newNode == NULL) { printf("Queue Overflow\n"); return; } newNode->data = value; newNode->next = NULL; if (rear == NULL) { // queue is empty front = rear = newNode; return; } rear->next = newNode; // link at rear rear = newNode; // update rear }Diagram (Enqueue 10, 20, 30):
After Enqueue(10): FRONT -> [10|NULL] <- REAR After Enqueue(20): FRONT -> [10|*] -> [20|NULL] <- REAR After Enqueue(30): FRONT -> [10|*] -> [20|*] -> [30|NULL] <- REAR
ii. DEQUEUE Operation (Delete from front)
Steps:
- Check if queue is empty (front == NULL).
- Store the front node in a temporary pointer.
- Move
frontto the next node. - If
frontbecomes NULL, setrearto NULL as well. - Free the temporary node.
void dequeue() { if (front == NULL) { printf("Queue Underflow\n"); return; } struct Node* temp = front; printf("Dequeued: %d\n", temp->data); front = front->next; // move front forward if (front == NULL) { // queue became empty rear = NULL; } free(temp); // release the old front node }Diagram (Dequeue from FRONT -> [10|] -> [20|] -> [30|NULL] <- REAR):
After Dequeue() (removes 10): FRONT -> [20|*] -> [30|NULL] <- REAR After Dequeue() (removes 20): FRONT -> [30|NULL] <- REAR After Dequeue() (removes 30): FRONT = NULL, REAR = NULL (queue is empty again)
iii. DISPLAY Operation
void display() { if (front == NULL) { printf("Queue is empty\n"); return; } struct Node* temp = front; printf("Queue (front to rear): "); while (temp != NULL) { printf("%d ", temp->data); temp = temp->next; } printf("\n"); }
Conclusion
A linked list removes the fixed-size limitation of an array, so both structures grow and shrink with the data. In the stack only one pointer (
top) is needed and both PUSH and POP work at the head of the list, while the queue needs two pointers, since ENQUEUE attaches atrearand DEQUEUE detaches atfront. In both cases every operation touches a constant number of nodes, so PUSH, POP, ENQUEUE and DEQUEUE all run in O(1) time, and overflow occurs only whenmallocitself fails. - 45 marksCircular queue advantages and implementatiHideAnswer
Why do we need circular queue? Explain. [5]
In a simple linear queue implemented using an array, two pointers are maintained: - Front - points to the first element - Rear - points to the last element Consider a queue of size 5: After Enqueue A, B, C, D, E and then Dequeue A, B: No...
- 55 marksNumericalBFS and DFS tracing with examplesHideAnswer
Traverse the following graph using BFS and DFS. [5]
BFS and DFS Graph Traversal
STEP 1 - EXTRACT: Given Data
The question asks to traverse a graph using BFS and DFS, but the actual graph (the figure/diagram) is not included in the text provided. No adjacency list, adjacency matrix, edge set, or vertex set is given.
Missing data: The specific graph (vertices and edges) required to perform the traversal is not available. Without it, the exact traversal orders cannot be determined, since traversal output depends entirely on the graph structure and the chosen starting vertex.
Because the graph is unreadable/absent, I will present the methodology and demonstrate it on a clearly labelled representative example, while flagging that the numeric traversal order is example-dependent and not the "official" answer to the missing figure.
STEP 2 - SOLVE (using a representative example graph)
Example Graph
1 / \ 2 3 / \ \ 4 5 6Adjacency list:
- $1 \to 2, 3$
- $2 \to 4, 5$
- $3 \to 6$
- $4 \to$ (none)
- $5 \to$ (none)
- $6 \to$ (none)
Breadth First Search (BFS)
Idea: Use a Queue (FIFO); visit level by level.
Step Queue (front→back) Visited Action 1 [1] {1} Start at 1 2 [2, 3] {1,2,3} Dequeue 1, enqueue 2,3 3 [3, 4, 5] {1,2,3,4,5} Dequeue 2, enqueue 4,5 4 [4, 5, 6] {1,2,3,4,5,6} Dequeue 3, enqueue 6 5 [5, 6] - Dequeue 4 (no neighbors) 6 [6] - Dequeue 5 (no neighbors) 7 [] - Dequeue 6 (no neighbors) BFS Order: $$\boxed{1 \to 2 \to 3 \to 4 \to 5 \to 6}$$
Depth First Search (DFS)
Idea: Use a Stack (LIFO) or recursion; go deep before backtracking.
Step Action Visited 1 Visit 1 {1} 2 Visit 2 (first neighbor of 1) {1,2} 3 Visit 4 (first neighbor of 2) {1,2,4} 4 Backtrack to 2 (4 dead-end) {1,2,4} 5 Visit 5 {1,2,4,5} 6 Backtrack to 1 {1,2,4,5} 7 Visit 3 {1,2,4,5,3} 8 Visit 6 {1,2,4,5,3,6} DFS Order: $$\boxed{1 \to 2 \to 4 \to 5 \to 3 \to 6}$$
Comparison
Feature BFS DFS Data structure Queue (FIFO) Stack / Recursion Traversal manner Level by level Deepest branch first Order (this graph) $1,2,3,4,5,6$ $1,2,4,5,3,6$ Typical use Shortest path (unweighted) Topological sort, cycle detection
Note to examiner/student: The traversal orders above are valid only for the assumed example graph. If the real exam figure differs, apply the same procedure (queue for BFS, stack/recursion for DFS) to that graph's adjacency list to obtain the correct order.
- 65 marksNumericalInfix to postfix conversion using stackHideAnswer
Convert the infix expression 7 * 8 + 10 - 2 to postfix using stack. [5]
Given Data
Infix expression to convert: $$7 * 8 + 10 - 2$$
Operator precedence:
*,/: higher+,-: lower
Associativity: left to right.
Conversion Rules (Stack Method)
- Scan tokens left to right.
- Operand → append to output.
- Operator → pop operators from stack with precedence greater than or equal to the current one (for left-associative operators), append them to output, then push the current operator.
- End → pop all remaining operators to output.
Step-by-Step Trace
Step Token Action Stack (bottom→top) Output 1 7operand → output (empty) 72 *push *73 8operand → output *7 84 +*≥+so pop*; push++7 8 *5 10operand → output +7 8 * 106 -+≥-so pop+; push--7 8 * 10 +7 2operand → output -7 8 * 10 + 28 End pop -(empty) 7 8 * 10 + 2 -
Verification (evaluate postfix)
Given values: $7,8,+,*$ etc. Compute $7 \times 8 = 56$; $56 + 10 = 66$; $66 - 2 = 64$. Infix: $7 \times 8 + 10 - 2 = 56 + 10 - 2 = 64$. ✓ Matches.
Result
$$\boxed{7\ 8\ *\ 10\ +\ 2\ -}$$
- 75 marksDoubly circular linked list operationsHideAnswer
Explain the insertion and deletion of a node at first and last position of doubly circular linked list. [5]
Each node has three fields: PREV (pointer to previous node), DATA, and NEXT (pointer to next node). In a doubly circular linked list: - The last node's NEXT points to the first node - The first node's PREV points to the last node --- Ste...
- 85 marksTime complexity definition and measurementHideAnswer
Define time and space complexity. Discuss about Round Robin Algorithm for MST. [1+4]
Time and Space Complexity + Round Robin Algorithm for MST
(a) Time and Space Complexity
Time Complexity
Time complexity is a measure of the amount of time (number of basic operations) an algorithm takes to complete as a function of the input size n. It describes how the running time grows with increasing input.
Example: Linear search has time complexity O(n).
Space Complexity
Space complexity is a measure of the amount of memory space an algorithm requires as a function of the input size n. It includes both auxiliary space and space used by the input.
Example: An algorithm storing an n x n matrix has space complexity O(n²).
(b) Round Robin Algorithm for MST
Background
The Round Robin (also called Boruvka's Algorithm) is one of the oldest algorithms for finding a Minimum Spanning Tree (MST) of a weighted, connected, undirected graph.
- Proposed by Otakar Boruvka in 1926.
- It works by simultaneously growing multiple components and merging them.
Key Idea
In each round (phase), every component (initially each vertex is its own component) selects the minimum weight edge that connects it to a different component. All such edges are added to the MST, and components are merged.
Algorithm Steps
Input: Graph G = (V, E) with weighted edges Output: Minimum Spanning Tree T 1. Initialize each vertex as its own component. T = {} (empty set of MST edges) 2. Repeat until only one component remains: a. For each component C: - Find the minimum weight edge (u, v) such that u ∈ C and v ∉ C (cheapest outgoing edge). b. Add all such selected edges to T (avoid duplicates if two components select the same edge). c. Merge the connected components. 3. Return T as the MST.
Example
Consider the graph:
4 2 A ------B ------C | | | 6| |3 |1 | | | D ------E ------F 5 8Edges: A-B(4), B-C(2), A-D(6), B-E(3), C-F(1), D-E(5), E-F(8)
Round 1: Each vertex is its own component {A},{B},{C},{D},{E},{F}
Component Cheapest Edge A A-B (4) B B-C (2) C C-F (1) D D-E (5) E B-E (3) F C-F (1) Selected edges (removing duplicates): C-F(1), B-C(2), B-E(3), A-B(4), D-E(5)
After merging: {A,B,C,E,F} and {D} merge further -> one component.
MST edges: C-F, B-C, B-E, A-B, D-E
Total Weight: 1+2+3+4+5 = 15
Complexity Analysis
Measure Value Time Complexity O(E log V) Space Complexity O(V + E) - Each phase reduces the number of components by at least half.
- So there are at most O(log V) phases.
- Each phase scans all E edges.
Advantages
- Naturally parallelizable (all components work simultaneously).
- Efficient for dense graphs.
- Works well in distributed computing environments.
Summary
Boruvka's Round Robin Algorithm builds the MST by repeatedly selecting the minimum cost edge from each component and merging components until a single spanning tree is formed, achieving O(E log V) time complexity.
- 95 marksNumericalPre-order traversal methodHideAnswer
Traverse the following tree in pre-order and in-order. [5]
STEP 1 - EXTRACT: Given Data
Task: Traverse a given tree in pre-order and in-order.
Tree structure: The tree diagram/image is NOT provided in the question. Only the instruction and the mark allocation ([5]) are given.
Missing data: The actual tree (nodes and their parent/child relationships) is missing. Without the specific tree, an exact, verifiable set of traversal sequences cannot be produced. The correct output depends entirely on the omitted diagram.
Since the tree cannot be recovered, I will state the required methods precisely and demonstrate them on a clearly labelled assumed sample tree (so the traversal logic can still be checked), while noting this is illustrative only.
STEP 2 - SOLVE (using an assumed sample tree, since the real tree is missing)
Assumed Sample Tree
A / \ B C / \ / \ D E F G1. Pre-order Traversal (Root → Left → Right)
Rule: visit Root, then Left subtree, then Right subtree.
- Visit A (root)
- Left subtree of A (rooted at B): visit B, then D, then E
- Right subtree of A (rooted at C): visit C, then F, then G
$$\text{Pre-order: } A \to B \to D \to E \to C \to F \to G$$
2. In-order Traversal (Left → Root → Right)
Rule: traverse Left subtree, visit Root, traverse Right subtree.
- Left subtree of A: D, B, E
- Visit A
- Right subtree of A: F, C, G
$$\text{In-order: } D \to B \to E \to A \to F \to C \to G$$
Summary
Traversal Order Result Pre-order Root, Left, Right A, B, D, E, C, F, G In-order Left, Root, Right D, B, E, A, F, C, G
Important note: These results are valid only for the assumed sample tree shown above. Because the actual tree from the exam paper was not supplied, the definitive answer cannot be produced. If the real tree differs, apply the same rules:
- Pre-order = Root, Left, Right
- In-order = Left, Root, Right
- 105 marksBinary tree definition and applicationsHideAnswer
Define binary tree and binary search tree. List the applications of Binary tree. [2+3]
--- A binary tree is a tree data structure in which each node has at most two children, referred to as the left child and the right child. Formal Definition: A binary tree is either: - An empty tree (null), OR - A node consisting of a ro...
- 115 marksLimitations of recursionHideAnswer
List the limitation of recursion. How do you delete the node in BST? [2+3]
Limitations of Recursion and Deletion in BST
Limitations of Recursion [2 marks]
-
Stack Overflow: Each recursive call uses stack memory. For deep recursion (large input), the call stack may overflow, causing program crash.
-
High Memory Usage: Every function call requires stack frame allocation (for parameters, local variables, return address), consuming more memory than iterative solutions.
-
Slower Execution: Function call overhead (pushing/popping stack frames) makes recursion slower compared to equivalent iterative approaches.
-
Difficult to Trace/Debug: The flow of recursive programs is harder to follow and debug compared to iterative programs.
-
Redundant Computations: Without memoization, some recursive algorithms (e.g., naive Fibonacci) recompute the same subproblems repeatedly.
Deletion of a Node in BST [3 marks]
When deleting a node from a Binary Search Tree, there are three cases:
Case 1: Node is a Leaf Node (No Children)
- Simply remove the node by setting the parent's pointer to
NULL.
Delete 20: 30 30 / --> / 20 (NULL)
Case 2: Node has One Child
- Replace the node with its only child (bypass the node).
Delete 30: 30 20 / --> 20
Case 3: Node has Two Children
- Find the inorder successor (smallest node in the right subtree) OR inorder predecessor (largest node in the left subtree).
- Copy its value to the node to be deleted.
- Delete the inorder successor/predecessor (which has at most one child).
Delete 50: 50 60 / \ --> / \ 30 70 30 70 / 60 Inorder successor of 50 is 60. Copy 60 to node 50, then delete original 60.
Algorithm (Pseudocode)
DELETE(root, key): if root == NULL: return NULL if key < root.data: root.left = DELETE(root.left, key) else if key > root.data: root.right = DELETE(root.right, key) else: // Case 1 & 2: 0 or 1 child if root.left == NULL: return root.right else if root.right == NULL: return root.left // Case 3: 2 children successor = FIND_MIN(root.right) root.data = successor.data root.right = DELETE(root.right, successor.data) return root
Summary Table
Case Condition Action 1 No children Remove node directly 2 One child Replace node with its child 3 Two children Replace with inorder successor, then delete successor -
- 125 marksSimple queue implementationHideAnswer
What is simple queue? Describe about any three types of graphs. [2+3]
Simple Queue and Types of Graphs
Simple Queue [2 marks]
A simple queue (also called a linear queue) is a linear data structure that follows the FIFO (First In First Out) principle, meaning the element inserted first is the element removed first.
Key characteristics:
- Elements are inserted from the REAR end
- Elements are deleted from the FRONT end
- Once the rear reaches the maximum size, no more insertions are possible (even if space exists at the front after deletions)
FRONT REAR | | v v [ 10 | 20 | 30 | 40 | 50 ] ^ ^ Delete InsertBasic Operations:
- Enqueue: Insert an element at the rear
- Dequeue: Remove an element from the front
- Peek/Front: View the front element without removing it
Three Types of Graphs [3 marks]
A graph is a non-linear data structure consisting of a set of vertices (nodes) and edges (connections) represented as G = (V, E).
1. Directed Graph (Digraph)
A graph in which every edge has a specific direction is called a directed graph. The edges are represented as ordered pairs (u, v), meaning the edge goes from vertex u to vertex v but not necessarily from v to u.
A -----> B | | v v C -----> D- Edge (A, B) means A points to B
- Used in: web page linking, task scheduling
2. Undirected Graph
A graph in which edges have no direction is called an undirected graph. The edges are represented as unordered pairs {u, v}, meaning the connection is bidirectional.
A ----- B | | | | C ----- D- Edge {A, B} means both A connects to B and B connects to A
- Used in: social networks, road maps
3. Weighted Graph
A graph in which each edge is assigned a numerical value (weight or cost) is called a weighted graph. It can be either directed or undirected.
A ---5--- B | | 3 7 | | C ---2--- D- The weight may represent distance, cost, time, or capacity
- Used in: shortest path algorithms (Dijkstra's), network routing, GPS navigation
Note: Other types include cyclic/acyclic graphs, connected/disconnected graphs, and complete graphs.