BE Computer Engineering (Pokhara University) Data Structure and Algorithms (PU, CMP 160) Question Paper 2078 Nepal
This is the official BE Computer Engineering (Pokhara University) Data Structure and Algorithms (PU, CMP 160) question paper for 2078, as set in the regular annual examination. It carries 100 full marks and a time allowance of 180 minutes, across 11 questions. On Kekkei you can attempt this Data Structure and Algorithms (PU, CMP 160) 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 (Pokhara University) Data Structure and Algorithms (PU, CMP 160) 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 a queue as abstract data types, clearly stating the operations and the access policy (LIFO vs FIFO) of each. (b) Write an algorithm to convert an infix expression to its equivalent postfix form using a stack, and trace your algorithm on the expression A + B * (C - D) / E. (c) Explain how a circular queue overcomes the limitation of a simple linear queue implemented in an array, and write the conditions used to detect a full and an empty circular queue.
(a) Stack and Queue as Abstract Data Types
Stack (LIFO — Last In, First Out): A stack is a linear ADT in which insertion and deletion both occur at the same end, called the top. The element inserted most recently is the first to be removed.
Operations:
push(x)— insert elementxat the toppop()— remove and return the top elementpeek()/top()— return the top element without removing itisEmpty()— test whether the stack is empty
Queue (FIFO — First In, First Out): A queue is a linear ADT in which insertion occurs at one end (rear) and deletion at the other end (front). The element inserted first is the first to be removed.
Operations:
enqueue(x)— insert elementxat the reardequeue()— remove and return the front elementfront()— return the front element without removing itisEmpty()— test whether the queue is empty
(b) Infix to Postfix Conversion using a Stack
Algorithm:
Initialize an empty stack and an empty output string.
Scan the infix expression left to right:
1. If the token is an operand, append it to output.
2. If the token is '(', push it onto the stack.
3. If the token is ')', pop and append operators until '(' is
popped (discard the '(').
4. If the token is an operator o1:
while stack top is an operator o2 with
precedence(o2) > precedence(o1), OR
precedence(o2) == precedence(o1) and o1 is left-associative:
pop o2 and append to output
push o1.
After scanning, pop and append all remaining operators.
Precedence: *, / (high) > +, - (low); all are left-associative.
Trace on A + B * (C - D) / E:
| Token | Stack | Output |
|---|---|---|
| A | (empty) | A |
| + | + | A |
| B | + | A B |
| * | + * | A B |
| ( | + * ( | A B |
| C | + * ( | A B C |
| - | + * ( - | A B C |
| D | + * ( - | A B C D |
| ) | + * | A B C D - |
| / | + / | A B C D - * |
| E | + / | A B C D - * E |
| end | (empty) | A B C D - * E / + |
(Note: at /, * has equal precedence and is left-associative, so * is popped first; then / is pushed.)
Postfix result: A B C D - * E / +
(c) Circular Queue vs Linear Queue
In a simple linear array queue, front and rear only move forward. After repeated enqueue/dequeue operations, rear reaches the last index even though free cells exist at the beginning (vacated by dequeue). This false-full / wasted-space problem cannot be reused without shifting elements.
A circular queue treats the array as a ring: after the last index it wraps to index 0 using modulo arithmetic, so freed front cells are reused. Index update: rear = (rear + 1) % SIZE, front = (front + 1) % SIZE.
Conditions (using count, or the one-cell-gap method):
- Empty:
front == -1(orcount == 0). - Full:
(rear + 1) % SIZE == front(one-cell-gap method), orcount == SIZE.
(a) Construct a Binary Search Tree (BST) by inserting the following keys in the given order: 45, 15, 79, 90, 10, 55, 12, 20, 50. Show the tree after each insertion. (b) Write the inorder, preorder and postorder traversal sequences of the resulting tree. (c) Describe, with the help of diagrams, the procedure to delete a node that has two children from a BST, and apply it to delete the node 45 from the tree you constructed.
(a) BST Construction by inserting 45, 15, 79, 90, 10, 55, 12, 20, 50
Insert each key by comparing with nodes from the root, going left if smaller and right if larger.
- Insert 45 → root
45. - Insert 15 (<45) → left of 45.
- Insert 79 (>45) → right of 45.
- Insert 90 (>45,>79) → right of 79.
- Insert 10 (<45,<15) → left of 15.
- Insert 55 (>45,<79) → left of 79.
- Insert 12 (<45,<15,>10) → right of 10.
- Insert 20 (<45,>15) → right of 15.
- Insert 50 (>45,<79,<55) → left of 55.
Final tree:
45
/ \
15 79
/ \ / \
10 20 55 90
\ /
12 50
(b) Traversal Sequences
- Inorder (Left, Root, Right):
10, 12, 15, 20, 45, 50, 55, 79, 90(sorted order, as expected for a BST) - Preorder (Root, Left, Right):
45, 15, 10, 12, 20, 79, 55, 50, 90 - Postorder (Left, Right, Root):
12, 10, 20, 15, 50, 55, 90, 79, 45
(c) Deleting a Node with Two Children
Procedure: When the node to delete has two children, replace its key with its inorder successor (the smallest key in its right subtree) — or equivalently its inorder predecessor — then delete that successor node (which has at most one child, so it is easy to remove).
Steps to delete 45 (root, two children):
- Right subtree of 45 is rooted at 79. Its leftmost (smallest) node is 50 → inorder successor.
- Replace key
45with50. - Delete the original
50node. It was the left child of 55 and has no children, so simply remove it.
Tree after deletion:
50
/ \
15 79
/ \ / \
10 20 55 90
\
12
The BST property is preserved: 50 is greater than all keys in the left subtree and smaller than all remaining keys in the right subtree.
(a) Differentiate between the adjacency matrix and adjacency list representations of a graph, comparing their space and time requirements. (b) Explain the Breadth First Search (BFS) and Depth First Search (DFS) traversal techniques, mentioning the auxiliary data structure used by each. (c) Apply Dijkstra's algorithm to find the shortest path from source vertex A to all other vertices in a weighted graph of your choice (at least 5 vertices), showing the contents of the distance and visited sets at each step.
(a) Adjacency Matrix vs Adjacency List
For a graph with V vertices and E edges:
| Aspect | Adjacency Matrix | Adjacency List |
|---|---|---|
| Structure | V × V matrix, M[i][j]=1 if edge i–j | Array of V lists, each holding neighbours |
| Space | ||
| Check edge (u,v) | ||
| List all neighbours of u | ||
| Best for | Dense graphs | Sparse graphs |
(b) BFS and DFS
Breadth First Search (BFS): Explores the graph level by level — visits the source, then all its neighbours, then their unvisited neighbours, and so on. It uses a queue (FIFO) as the auxiliary structure and finds shortest paths in terms of edge count in an unweighted graph. Time: with an adjacency list.
Depth First Search (DFS): Explores as far as possible along one branch before backtracking. It uses a stack (LIFO) — explicitly, or implicitly via recursion. Useful for cycle detection, topological sort, connected components. Time: .
(c) Dijkstra's Algorithm
Consider this weighted graph (source A):
A-B = 4 A-C = 1
C-B = 2 C-D = 5
B-E = 3 D-E = 1
Edges: A–B(4), A–C(1), C–B(2), C–D(5), B–E(3), D–E(1). Vertices: A,B,C,D,E.
Maintain a distance set dist[] (initially 0 for A, ∞ for others) and a visited set. Repeatedly pick the unvisited vertex with smallest distance and relax its edges.
| Step | Picked | dist[A] | dist[B] | dist[C] | dist[D] | dist[E] | Visited |
|---|---|---|---|---|---|---|---|
| init | — | 0 | ∞ | ∞ | ∞ | ∞ | {} |
| 1 | A | 0 | 4 | 1 | ∞ | ∞ | {A} |
| 2 | C | 0 | 3 | 1 | 6 | ∞ | {A,C} |
| 3 | B | 0 | 3 | 1 | 6 | 6 | {A,C,B} |
| 4 | E | 0 | 3 | 1 | 6 | 6 | {A,C,B,E} |
| 5 | D | 0 | 3 | 1 | 6 | 6 | {A,C,B,E,D} |
At step 2, C relaxes B: 1+2=3 < 4. At step 3, B relaxes E: 3+3=6. At step 5, D relaxes E: 6+1=7 > 6, no change.
Final shortest distances from A: A=0, B=3 (A→C→B), C=1 (A→C), D=6 (A→C→D), E=6 (A→C→B→E).
(a) Explain the working principle of Quick Sort with a suitable example, clearly describing the partitioning step. (b) Sort the array [38, 27, 43, 3, 9, 82, 10] using Merge Sort and show every level of division and merging. (c) Derive the best-case, average-case and worst-case time complexities of Quick Sort and explain under what input condition the worst case occurs.
(a) Quick Sort and the Partition Step
Quick Sort is a divide-and-conquer algorithm. It chooses a pivot, then partitions the array so that all elements smaller than the pivot lie to its left and all larger to its right; the pivot is then in its final sorted position. The two partitions are sorted recursively.
Partitioning (Lomuto scheme, pivot = last element):
partition(A, lo, hi):
pivot = A[hi]; i = lo - 1
for j = lo to hi-1:
if A[j] <= pivot:
i = i + 1; swap A[i], A[j]
swap A[i+1], A[hi]
return i+1 // final pivot index
Example on [7, 2, 9, 3], pivot = 3: elements ≤3 (2) moved left → [2, 3, 9, 7] with 3 in place; recurse on [2] and [9,7] → sorted [2,3,7,9].
(b) Merge Sort of [38, 27, 43, 3, 9, 82, 10]
Division:
[38, 27, 43, 3, 9, 82, 10]
-> [38, 27, 43, 3] [9, 82, 10]
-> [38,27] [43,3] [9,82] [10]
-> [38][27] [43][3] [9][82] [10]
Merging (combine sorted halves):
[38]+[27] -> [27,38]
[43]+[3] -> [3,43]
[27,38]+[3,43] -> [3,27,38,43]
[9]+[82] -> [9,82]
[9,82]+[10] -> [9,10,82]
[3,27,38,43] + [9,10,82] -> [3,9,10,27,38,43,82]
Sorted array: [3, 9, 10, 27, 38, 43, 82].
(c) Time Complexity of Quick Sort
Let be the running time on elements; partitioning costs .
- Best case — pivot splits the array into two equal halves:
- Average case — random/typical input, reasonably balanced splits: .
- Worst case — pivot is always the smallest or largest element, giving splits of size and :
Worst-case input condition: the array is already sorted (ascending or descending) when the first or last element is chosen as pivot, producing maximally unbalanced partitions. Using a randomized or median-of-three pivot makes the worst case very unlikely. Space: average recursion stack ( worst case).
Section B: Short Answer Questions
Attempt all / any as specified.
Write a recursive function to compute the n-th Fibonacci number. Draw the recursion tree for fib(5), and explain why this recursive approach has exponential time complexity. Suggest one technique to improve its efficiency.
Recursive Fibonacci
int fib(int n) {
if (n <= 1)
return n; // fib(0)=0, fib(1)=1
return fib(n-1) + fib(n-2);
}
Recursion Tree for fib(5)
fib(5)
/ \
fib(4) fib(3)
/ \ / \
fib(3) fib(2) fib(2) fib(1)
/ \ / \ / \
fib(2) f(1) f(1) f(0) f(1) f(0)
/ \
f(1) f(0)
Many subproblems (e.g. fib(3), fib(2)) are recomputed multiple times.
Why Exponential
Each call spawns two more calls, so the number of calls roughly doubles with n. The recurrence is , whose solution grows like where — i.e. exponential, . The same values are computed over and over (overlapping subproblems).
Improvement
Use memoization (top-down DP) — store each computed fib(i) in an array/cache and reuse it — or bottom-up dynamic programming iterating from fib(0) upward. This reduces the time to (and space to for the iterative two-variable version).
Write an algorithm to reverse a singly linked list in place (without using extra nodes), and explain its time and space complexity. List two advantages of a doubly linked list over a singly linked list.
Reverse a Singly Linked List In Place
Use three pointers and reverse each next link while traversing once.
Node* reverse(Node* head) {
Node *prev = NULL, *curr = head, *next = NULL;
while (curr != NULL) {
next = curr->next; // save next node
curr->next = prev; // reverse the link
prev = curr; // advance prev
curr = next; // advance curr
}
return prev; // new head
}
Complexity
- Time: — each node is visited exactly once.
- Space: — only a constant number of pointers are used; no extra nodes are allocated (in-place).
Two Advantages of Doubly over Singly Linked List
- Bidirectional traversal: a doubly linked list can be traversed both forward and backward using its
prevandnextpointers. - Easier deletion / insertion before a node: given a pointer to a node, it can be deleted in (the previous node is directly accessible via
prev), whereas a singly linked list needs the predecessor to be found first.
What is a hash collision? Insert the keys 12, 22, 32, 42, 52 into a hash table of size 10 using the hash function h(k) = k mod 10, resolving collisions using (a) linear probing and (b) separate chaining. Show the resulting table in each case.
Hash Collision
A hash collision occurs when two distinct keys map to the same index of the hash table under the hash function, i.e. h(k1) == h(k2) for k1 ≠ k2. A collision-resolution method is then required to store both keys.
Here h(k) = k mod 10, so all keys 12, 22, 32, 42, 52 hash to index 2 — every insertion after the first collides.
(a) Linear Probing
On collision, probe the next slot: (h(k) + i) mod 10, i = 0,1,2,...
- 12 → 2 (empty) → index 2
- 22 → 2 occupied → 3 → index 3
- 32 → 2,3 occupied → 4 → index 4
- 42 → 2,3,4 occupied → 5 → index 5
- 52 → 2,3,4,5 occupied → 6 → index 6
| Index | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|---|---|---|---|---|---|---|---|---|---|---|
| Key | 12 | 22 | 32 | 42 | 52 |
(b) Separate Chaining
Each slot holds a linked list of all keys hashing to it. All five keys hash to index 2:
| Index | Chain |
|---|---|
| 0 | — |
| 1 | — |
| 2 | 12 → 22 → 32 → 42 → 52 |
| 3–9 | — |
In chaining, no probing is needed; collisions are simply appended to the list at that index.
Define Big-O, Big-Omega and Big-Theta notations. Arrange the following functions in increasing order of growth rate: n!, n log n, 2^n, n^2, log n, n. Justify the placement of n log n relative to n^2.
Asymptotic Notations
Let and be non-negative functions.
- Big-O () — upper bound: if there exist constants such that for all . Describes the worst-case growth.
- Big-Omega () — lower bound: if for all . Describes the best-case / minimum growth.
- Big-Theta () — tight bound: if it is both and , i.e. . The function grows exactly at that rate.
Increasing Order of Growth
Justification: vs
Divide both by : we compare with . Since grows much more slowly than (for large , ), it follows that . Hence is placed before in the ordering.
Write the algorithm for binary search on a sorted array and trace it to search for the key 23 in the array [2, 5, 8, 12, 16, 23, 38, 56, 72, 91]. Explain why binary search cannot be applied directly to a singly linked list.
Binary Search Algorithm (sorted array)
int binarySearch(int A[], int n, int key) {
int low = 0, high = n - 1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (A[mid] == key) return mid; // found
else if (A[mid] < key) low = mid + 1; // search right half
else high = mid - 1; // search left half
}
return -1; // not found
}
Trace: search 23 in [2, 5, 8, 12, 16, 23, 38, 56, 72, 91] (indices 0–9)
| Step | low | high | mid | A[mid] | Action |
|---|---|---|---|---|---|
| 1 | 0 | 9 | 4 | 16 | 16 < 23 → low = 5 |
| 2 | 5 | 9 | 7 | 56 | 56 > 23 → high = 6 |
| 3 | 5 | 6 | 5 | 23 | found at index 5 |
Key 23 is found at index 5 in 3 comparisons. Time complexity: .
Why Not on a Singly Linked List
Binary search needs constant-time random access to the middle element. A singly linked list provides only sequential access — reaching the middle node requires traversing from the head in time, and the list cannot be indexed directly. This destroys the advantage, so binary search cannot be applied efficiently to a singly linked list.
What is an AVL tree? Insert the keys 30, 20, 10 into an empty AVL tree and show the rotation required to keep it balanced, naming the type of rotation performed. State the balance factor condition that every node of an AVL tree must satisfy.
AVL Tree
An AVL tree is a self-balancing Binary Search Tree in which, for every node, the heights of the left and right subtrees differ by at most 1. This keeps the tree height , guaranteeing search, insert and delete.
Balance Factor Condition
For every node: , and it must satisfy
If any node's balance factor becomes or after an insertion, a rotation restores balance.
Inserting 30, 20, 10
- Insert 30 → root.
- Insert 20 (<30) → left child. Tree still balanced (BF of 30 = +1).
30
/
20
- Insert 10 (<30,<20) → left child of 20.
30 (BF = +2 -> unbalanced)
/
20
/
10
Node 30 now has balance factor with the imbalance in the left-left subtree.
Rotation required: Single Right Rotation (LL rotation) about node 30.
After rotation (balanced):
20
/ \
10 30
Every node now has balance factor in , so the AVL property is restored.
Differentiate between a stack and a queue with respect to insertion and deletion, and give one real-world application of each. Also explain how two stacks can be used to implement a queue.
Stack vs Queue
| Aspect | Stack | Queue |
|---|---|---|
| Policy | LIFO (Last In, First Out) | FIFO (First In, First Out) |
| Insertion | At one end — push at top | At the rear — enqueue |
| Deletion | From the same end — pop at top | From the front — dequeue |
Real-world applications:
- Stack: function call/return management (call stack), undo operation in editors, expression evaluation.
- Queue: CPU/printer job scheduling, handling requests on a server (first-come first-served).
Implementing a Queue using Two Stacks
Use two stacks inStack and outStack.
- Enqueue(x): push
xontoinStack. - Dequeue(): if
outStackis empty, pop every element frominStackand push it ontooutStack(this reverses the order). Then pop and return the top ofoutStack.
Because the elements are reversed once when transferred, the element that entered first ends up on top of outStack, giving FIFO behaviour. Each element is pushed and popped at most twice, so the amortized cost per operation is .
Frequently asked questions
- Where can I find the BE Computer Engineering (Pokhara University) Data Structure and Algorithms (PU, CMP 160) question paper 2078?
- The full BE Computer Engineering (Pokhara University) Data Structure and Algorithms (PU, CMP 160) 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 Algorithms (PU, CMP 160) 2078 paper come with solutions?
- Yes. Every question on this Data Structure and Algorithms (PU, CMP 160) 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 (Pokhara University) Data Structure and Algorithms (PU, CMP 160) 2078 paper?
- The BE Computer Engineering (Pokhara University) Data Structure and Algorithms (PU, CMP 160) 2078 paper carries 100 full marks and is meant to be completed in 180 minutes, across 11 questions.
- Is practising this Data Structure and Algorithms (PU, CMP 160) past paper free?
- Yes — reading and attempting this Data Structure and Algorithms (PU, CMP 160) past paper on Kekkei is completely free.