BE Computer Engineering (IOE, TU) Data Structure and Algorithm (IOE, CT 552) Question Paper 2078 Nepal
This is the official BE Computer Engineering (IOE, TU) Data Structure and Algorithm (IOE, CT 552) question paper for 2078, as set in the regular annual examination. It carries 80 full marks and a time allowance of 180 minutes, across 11 questions. On Kekkei you can attempt this Data Structure and Algorithm (IOE, CT 552) past paper online with a timer, get instant AI feedback and step-by-step solutions, and track the topics where you lose marks — completely free. Whether you are revising for your BE Computer Engineering (IOE, TU) Data Structure and Algorithm (IOE, CT 552) exam or solving previous years' question papers, this 2078 paper is a great way to practise under real exam conditions.
Section A: Long Answer Questions
Attempt all / any as specified.
(a) Define a stack and list its basic operations (PUSH, POP, PEEK) along with the overflow and underflow conditions. Write an algorithm to implement these operations using a one-dimensional array. (6)
(b) Convert the following infix expression into its equivalent postfix expression using a stack, showing the stack and output at each step:
A + ( B * C - ( D / E ^ F ) * G ) * H
Then explain how the resulting postfix expression is evaluated using a stack. (6)
(a) Stack: definition, operations and array implementation
A stack is a linear data structure that follows the LIFO (Last-In-First-Out) principle: the element inserted last is the one removed first. All insertions and deletions take place at one end called the top.
Basic operations
- PUSH(x) — insert element
xat the top of the stack. - POP() — remove and return the top element.
- PEEK() (or TOP) — return the top element without removing it.
Overflow and underflow (array of size MAX, top initialised to -1)
- Overflow: attempting to PUSH when
top == MAX - 1(stack full). - Underflow: attempting to POP/PEEK when
top == -1(stack empty).
#define MAX 100
int stack[MAX];
int top = -1;
void push(int x) {
if (top == MAX - 1) // overflow check
printf("Stack Overflow\n");
else
stack[++top] = x;
}
int pop() {
if (top == -1) { // underflow check
printf("Stack Underflow\n");
return -1;
}
return stack[top--];
}
int peek() {
if (top == -1) {
printf("Stack Empty\n");
return -1;
}
return stack[top];
}
(b) Infix to postfix conversion
Expression: A + ( B * C - ( D / E ^ F ) * G ) * H
Precedence: ^ (highest, right-associative) > * / > + -. We scan left to right; operands go to output, operators are managed on the stack.
| Symbol | Stack (bottom→top) | Output |
|---|---|---|
| A | (empty) | A |
| + | + | A |
| ( | + ( | A |
| B | + ( | A B |
| * | + ( * | A B |
| C | + ( * | A B C |
| - | + ( - | A B C * |
| ( | + ( - ( | A B C * |
| D | + ( - ( | A B C * D |
| / | + ( - ( / | A B C * D |
| E | + ( - ( / | A B C * D E |
| ^ | + ( - ( / ^ | A B C * D E |
| F | + ( - ( / ^ | A B C * D E F |
| ) | + ( - | A B C * D E F ^ / |
| * | + ( - * | A B C * D E F ^ / |
| G | + ( - * | A B C * D E F ^ / G |
| ) | + | A B C * D E F ^ / G * - |
| * | + * | A B C * D E F ^ / G * - |
| H | + * | A B C * D E F ^ / G * - H |
| end | (empty) | A B C * D E F ^ / G * - H * + |
Postfix: A B C * D E F ^ / G * - H * +
Evaluation using a stack: Scan the postfix expression left to right. Push every operand onto the stack. On meeting an operator, pop the top two operands (the first popped is the right operand, the second is the left), apply the operator, and push the result back. After the whole string is scanned, the single value remaining on the stack is the final result.
(a) Define a Binary Search Tree (BST). Starting from an empty tree, insert the following keys one by one and draw the resulting BST: 45, 30, 60, 25, 40, 55, 70, 35. (5)
(b) Write the inorder, preorder and postorder traversal sequences of the BST obtained in part (a). (3)
(c) From the BST in part (a), delete node 30 and then node 60. Draw the tree after each deletion and clearly explain the rule you applied for deleting a node that has two children. (4)
(a) Binary Search Tree and insertion
A Binary Search Tree (BST) is a binary tree in which, for every node, all keys in its left subtree are smaller than the node's key and all keys in its right subtree are greater (no duplicates). This ordering allows search, insertion and deletion in time, where is the height.
Inserting 45, 30, 60, 25, 40, 55, 70, 35 (45 is the root; each key goes left if smaller, right if larger):
45
/ \
30 60
/ \ / \
25 40 55 70
/
35
(b) Traversals of the BST
- Inorder (Left, Root, Right) — gives sorted order: 25, 30, 35, 40, 45, 55, 60, 70
- Preorder (Root, Left, Right): 45, 30, 25, 40, 35, 60, 55, 70
- Postorder (Left, Right, Root): 25, 35, 40, 30, 55, 70, 60, 45
(c) Deletions
Rule for deleting a node with two children: replace the node's key with its inorder successor (the smallest key in its right subtree) — or equivalently the inorder predecessor — then delete that successor node, which has at most one child.
Delete 30 (it has two children: 25 and 40). Inorder successor of 30 is 35 (smallest in the right subtree rooted at 40). Replace 30 with 35 and remove the original 35:
45
/ \
35 60
/ \ / \
25 40 55 70
Delete 60 (two children: 55 and 70). Inorder successor is 70 (smallest in its right subtree). Replace 60 with 70 and remove the leaf 70:
45
/ \
35 70
/ \ /
25 40 55
(a) Differentiate between the adjacency matrix and adjacency list representations of a graph, commenting on their space requirements. (4)
(b) Write the algorithms for Depth First Search (DFS) and Breadth First Search (BFS) traversal of a graph, mentioning the auxiliary data structure each one uses. (4)
(c) For the graph given below, show the order in which vertices are visited using both DFS and BFS, starting from vertex A. Assume adjacent vertices are visited in alphabetical order.
A - B, A - C
B - D, B - E
C - F
E - F, E - G
(4)
(a) Adjacency matrix vs adjacency list
For a graph with vertices and edges:
| Feature | Adjacency Matrix | Adjacency List |
|---|---|---|
| Structure | 2-D array; M[i][j]=1 if edge exists | Array of lists; list i holds neighbours of i |
| Space | regardless of edges | |
| Best for | Dense graphs | Sparse graphs |
| Check edge (u,v) | ||
| List all neighbours of u |
A matrix wastes space on sparse graphs because it stores a slot for every possible edge; a list stores only existing edges, so it is far more space-efficient when .
(b) DFS and BFS algorithms
DFS uses a stack (explicitly, or implicitly via recursion):
DFS(G, s):
mark all vertices unvisited
push s onto stack
while stack not empty:
v = pop()
if v not visited:
visit v; mark visited
push all unvisited neighbours of v
BFS uses a queue:
BFS(G, s):
mark all vertices unvisited
visit s; mark visited; enqueue s
while queue not empty:
v = dequeue()
for each unvisited neighbour w of v:
visit w; mark visited; enqueue w
(c) Traversal starting from A (neighbours in alphabetical order)
Adjacency: A→B,C B→D,E C→F E→F,G
- DFS (A): start A → B → D (dead end, backtrack) → E → F (dead end) → G (dead end), backtrack to A → C (its neighbour F already visited). Visiting order: A, B, D, E, F, G, C.
- BFS (A): level by level — A | B, C | D, E, F | G → A, B, C, D, E, F, G
(a) Write the algorithm for Quick Sort and explain the working of the partition step with the role of the pivot element. (6)
(b) Sort the following list in ascending order using Quick Sort, choosing the first element as the pivot, and show the array after each partitioning pass:
38, 27, 43, 3, 9, 82, 10
(4)
(c) Derive the best-case and worst-case time complexity of Quick Sort and state when the worst case occurs. (2)
(a) Quick Sort algorithm and partitioning
Quick Sort is a divide-and-conquer sorting algorithm. It picks a pivot, partitions the array so that all elements smaller than the pivot lie to its left and all larger to its right (the pivot reaches its final sorted position), then recursively sorts the two partitions.
QUICKSORT(A, low, high):
if low < high:
p = PARTITION(A, low, high) // pivot index
QUICKSORT(A, low, p - 1)
QUICKSORT(A, p + 1, high)
PARTITION(A, low, high): // first element as pivot
pivot = A[low]
i = low + 1; j = high
while true:
while i <= j and A[i] <= pivot: i++
while i <= j and A[j] > pivot: j--
if i < j: swap(A[i], A[j])
else: break
swap(A[low], A[j]) // place pivot in correct slot
return j
Role of the pivot: the pivot is the reference element. The partition step rearranges the array around it so the pivot lands in its correct final position, splitting the problem into two independent smaller sub-arrays.
(b) Sorting 38, 27, 43, 3, 9, 82, 10 (first element as pivot)
Pass 1 — pivot = 38: elements ≤38 to the left, >38 to the right.
Result: [27, 3, 9, 10] 38 [82, 43] → 27 3 9 10 38 82 43
Left sub-array 27, 3, 9, 10 — pivot = 27:
→ [3, 9, 10] 27 → 3 9 10 27
3, 9, 10pivot 3 →3 [9, 10];9,10pivot 9 →9 10. Left part sorted:3 9 10 27.
Right sub-array 82, 43 — pivot = 82:
→ [43] 82 → 43 82
Final sorted array: 3, 9, 10, 27, 38, 43, 82
(c) Time complexity
- Best case — pivot splits the array into two nearly equal halves: .
- Worst case — pivot is always the smallest or largest element, giving partitions of sizes and : .
- The worst case occurs when the array is already sorted (or reverse-sorted) and the first/last element is chosen as pivot.
Section B: Short Answer Questions
Attempt all / any as specified.
(a) Differentiate between a singly linked list and a doubly linked list with neat diagrams. (3)
(b) Write an algorithm to insert a new node at the beginning and to delete a node from the end of a singly linked list. (5)
(a) Singly vs doubly linked list
| Feature | Singly Linked List | Doubly Linked List |
|---|---|---|
| Pointers per node | one (next) | two (prev, next) |
| Traversal | forward only | both directions |
| Memory | less (1 pointer) | more (2 pointers) |
| Delete given node | needs previous node | direct via prev |
Singly: [data|next] -> [data|next] -> [data|NULL]
Doubly: NULL <- [prev|data|next] <-> [prev|data|next] -> NULL
(b) Algorithms
Insert at beginning
INSERT_FRONT(head, x):
new = allocate node
new.data = x
new.next = head
head = new // new node becomes head
return head
Delete from end
DELETE_END(head):
if head == NULL: return NULL // empty
if head.next == NULL: // single node
free(head); return NULL
temp = head
while temp.next.next != NULL: // stop at 2nd-last
temp = temp.next
free(temp.next)
temp.next = NULL
return head
(a) What is a circular queue? Explain how it overcomes the limitation of a linear queue implemented using an array. (4)
(b) For a circular queue of size 5, show the contents of the array, FRONT and REAR after the following sequence of operations: enqueue(10), enqueue(20), enqueue(30), dequeue(), enqueue(40), enqueue(50), enqueue(60). (4)
(a) Circular queue
A circular queue is a linear queue in which the last position is logically connected back to the first position, forming a circle. Indices wrap around using modulo arithmetic: REAR = (REAR + 1) % SIZE and FRONT = (FRONT + 1) % SIZE.
Limitation of a linear array queue it solves: in a simple linear queue, when REAR reaches the last index the queue is treated as full even if cells at the front were freed by dequeues — this is false overflow and wastes space. A circular queue reuses those vacated front cells by wrapping REAR around, so space is fully utilised without shifting elements.
(b) Trace for circular queue of size 5 (indices 0–4)
Start: FRONT = -1, REAR = -1 (empty).
| Operation | Array [0..4] | FRONT | REAR |
|---|---|---|---|
| enqueue(10) | 10 . . . . | 0 | 0 |
| enqueue(20) | 10 20 . . . | 0 | 1 |
| enqueue(30) | 10 20 30 . . | 0 | 2 |
| dequeue() (removes 10) | . 20 30 . . | 1 | 2 |
| enqueue(40) | . 20 30 40 . | 1 | 3 |
| enqueue(50) | . 20 30 40 50 | 1 | 4 |
| enqueue(60) | 60 20 30 40 50 | 1 | 0 |
Final: array = 60, 20, 30, 40, 50, FRONT = 1, REAR = 0 (REAR wrapped around to index 0). The queue is now full.
(a) Define recursion and explain the difference between a recursive and an iterative solution with respect to memory usage. (3)
(b) Write a recursive function to solve the Tower of Hanoi problem for n disks and determine the total number of moves required for n = 4 disks. (5)
(a) Recursion
Recursion is a technique in which a function calls itself (directly or indirectly) to solve a problem by reducing it to smaller instances of the same problem, with a base case that stops the recursion.
Memory usage — recursive vs iterative: a recursive solution uses the call stack: each pending call adds a stack frame (storing parameters, local variables, return address), so memory grows with the recursion depth, extra space, and deep recursion may cause stack overflow. An iterative solution uses a loop with a fixed set of variables, typically requiring only extra space, making it more memory-efficient.
(b) Tower of Hanoi
void hanoi(int n, char src, char aux, char dst) {
if (n == 1) {
printf("Move disk 1 from %c to %c\n", src, dst);
return;
}
hanoi(n - 1, src, dst, aux); // move top n-1 to auxiliary
printf("Move disk %d from %c to %c\n", n, src, dst);
hanoi(n - 1, aux, src, dst); // move n-1 from aux to dest
}
Number of moves: the recurrence is , , giving .
For : moves.
(a) Define a hash function and explain what is meant by a collision in hashing. (3)
(b) Insert the keys 23, 43, 13, 27, 33 into a hash table of size 10 using the hash function h(k) = k mod 10, resolving collisions by linear probing. Show the final table. (5)
(a) Hash function and collision
A hash function maps a key to an index in a hash table (typically to ), ideally distributing keys uniformly so that lookup, insertion and deletion take average time.
A collision occurs when two distinct keys hash to the same index, i.e. . Collisions are unavoidable when the number of keys exceeds the table size, and must be handled by a collision-resolution method (e.g. linear probing, chaining).
(b) Insert 23, 43, 13, 27, 33 with h(k)=k mod 10, linear probing
| Key | h(k) | Probe sequence | Final index |
|---|---|---|---|
| 23 | 3 | 3 free | 3 |
| 43 | 3 | 3 taken → 4 free | 4 |
| 13 | 3 | 3,4 taken → 5 free | 5 |
| 27 | 7 | 7 free | 7 |
| 33 | 3 | 3,4,5 taken → 6 free | 6 |
Final hash table:
| Index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|---|
| Key | - | - | - | 23 | 43 | 13 | 33 | 27 | - | - |
(a) Write the algorithm for binary search and state the precondition that the input must satisfy. (4)
(b) Trace binary search to locate the key 23 in the sorted array [4, 8, 15, 16, 23, 42, 50], showing the values of low, high and mid at each step, and derive its time complexity. (4)
(a) Binary search algorithm
Precondition: the input array must be sorted (here, in ascending order).
BINARY_SEARCH(A, n, key):
low = 0; high = n - 1
while low <= high:
mid = (low + high) / 2 // integer division
if A[mid] == key: return mid // found
else if A[mid] < key: low = mid + 1
else: high = mid - 1
return -1 // not found
(b) Trace: find 23 in [4, 8, 15, 16, 23, 42, 50] (indices 0–6)
| Step | low | high | mid | A[mid] | Action |
|---|---|---|---|---|---|
| 1 | 0 | 6 | 3 | 16 | 16 < 23 → low = 4 |
| 2 | 4 | 6 | 5 | 42 | 42 > 23 → high = 4 |
| 3 | 4 | 4 | 4 | 23 | found at index 4 |
Key 23 found at index 4 in 3 comparisons.
Time complexity: each step halves the search interval, so the number of comparisons is at most . Hence binary search runs in in the worst and average case, and in the best case (key at the first mid).
(a) Define Big-O, Big-Omega (Ω) and Big-Theta (Θ) asymptotic notations. (4)
(b) Determine the time complexity of the following code fragment in terms of Big-O notation and justify your answer:
for (i = 1; i <= n; i++) {
for (j = 1; j <= n; j = j * 2) {
printf("%d", i + j);
}
}
(4)
(a) Asymptotic notations
For functions and :
- Big-O (upper bound): if there exist constants and such that for all . Describes the worst-case / maximum growth rate.
- Big-Omega (, lower bound): if there exist such that for all . Describes the minimum growth rate.
- Big-Theta (, tight bound): if there exist such that for all , i.e. is both and .
(b) Complexity of the code
for (i = 1; i <= n; i++) // outer: runs n times
for (j = 1; j <= n; j = j * 2) // inner: j doubles each time
printf("%d", i + j);
- The outer loop runs times.
- The inner loop multiplies
jby 2 each iteration (), so it executes about times, independent ofi.
Total work .
Time complexity = .
(a) Define a heap and differentiate between a max-heap and a min-heap. (3)
(b) Build a max-heap from the following list of elements by successive insertion and draw the final heap, then show the array after performing one delete-max operation:
12, 19, 16, 1, 4, 7
(5)
(a) Heap, max-heap and min-heap
A heap is a complete binary tree (all levels full except possibly the last, which fills left to right) that satisfies the heap property at every node. It is usually stored in an array, where for node at index i the children are at 2i+1 and 2i+2.
- Max-heap: every parent is ≥ its children, so the maximum element is at the root.
- Min-heap: every parent is ≤ its children, so the minimum element is at the root.
(b) Build max-heap from 12, 19, 16, 1, 4, 7 by successive insertion
Insert each element at the end and sift up (swap with parent while larger):
- Insert 12:
12 - Insert 19: 19>12 → swap →
19, 12 - Insert 16: 16<19 →
19, 12, 16 - Insert 1:
19, 12, 16, 1 - Insert 4:
19, 12, 16, 1, 4 - Insert 7: 7<16 →
19, 12, 16, 1, 4, 7
Final max-heap array: 19, 12, 16, 1, 4, 7
19
/ \
12 16
/ \ /
1 4 7
One delete-max operation: remove the root (19), move the last element (7) to the root, then sift down.
- After moving 7 to root:
7, 12, 16, 1, 4 - Children of 7 are 12 and 16; largest is 16 → swap 7 and 16:
16, 12, 7, 1, 4 - 7 now a leaf → done.
Array after delete-max: 16, 12, 7, 1, 4
16
/ \
12 7
/ \
1 4
Frequently asked questions
- Where can I find the BE Computer Engineering (IOE, TU) Data Structure and Algorithm (IOE, CT 552) question paper 2078?
- The full BE Computer Engineering (IOE, TU) Data Structure and Algorithm (IOE, CT 552) 2078 (regular) question paper is available free on Kekkei. You can read every question online and attempt the paper under timed exam conditions.
- Does the Data Structure and Algorithm (IOE, CT 552) 2078 paper come with solutions?
- Yes. Every question on this Data Structure and Algorithm (IOE, CT 552) past paper includes a step-by-step solution, plus instant AI feedback when you attempt it on Kekkei.
- How many marks is the BE Computer Engineering (IOE, TU) Data Structure and Algorithm (IOE, CT 552) 2078 paper?
- The BE Computer Engineering (IOE, TU) Data Structure and Algorithm (IOE, CT 552) 2078 paper carries 80 full marks and is meant to be completed in 180 minutes, across 11 questions.
- Is practising this Data Structure and Algorithm (IOE, CT 552) past paper free?
- Yes — reading and attempting this Data Structure and Algorithm (IOE, CT 552) past paper on Kekkei is completely free.