Skip to main content

Chapter 4

Data Structures and Algorithms

TU BSc CSIT past exam questions

Past questions and answers

84 questions set from this chapter. Most repeated first.

  • 2080 · 5 marks

How can you use linked list to implement stack? Explain.

Similar questions: Define list. How can you use linked (2081)

Answer

A stack follows LIFO, so with a singly linked list the head of the list is used as the top of the stack. Inserting and deleting at the head takes O(1)O(1) time, and the stack grows and shrinks dynamically, so there is no fixed-size overflow.

struct node {
    int data;
    struct node *next;
};
struct node *top = NULL;

Push(x):

  1. Allocate a new node n and set n->data = x.
  2. Set n->next = top (link it to the current top).
  3. Set top = n.
void push(int x) {
    struct node *n = (struct node *)malloc(sizeof(struct node));
    if (n == NULL) { printf("Overflow\n"); return; }
    n->data = x;
    n->next = top;
    top = n;
}

Pop():

  1. If top == NULL, the stack is empty (underflow).
  2. Otherwise save t = top, set top = top->next, read x = t->data, free(t) and return x.
int pop() {
    if (top == NULL) { printf("Underflow\n"); return -1; }
    struct node *t = top;
    int x = t->data;
    top = top->next;
    free(t);
    return x;
}

Example: push 10, 20, 30 gives top -> 30 -> 20 -> 10 -> NULL. A pop returns 30 and leaves top -> 20 -> 10. The stack is empty when top == NULL. Memory is used only for stored items, at the cost of an extra pointer per element.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2081 · 10 marks

Define list. How can you use linked list to implement stack? Explain circular linked list.

Similar questions: How can you use linked list to (2080)

Answer

List. A list is a finite, ordered collection of elements of the same type in which every element has a position (first, second, ... last). Typical operations are insert, delete, search, traverse and count. A list can be stored contiguously in an array (static, fixed size) or as a linked list, in which each element is a node holding the data and a pointer to the next node, so the list can grow and shrink at run time.

struct node {
    int data;
    struct node *next;
};

Implementing a stack with a linked list. A stack is a LIFO structure: insertion (push) and deletion (pop) take place only at one end, the top. In a linked list, inserting and deleting at the head (front) takes O(1)O(1) time, so the head of the list is used as the top of the stack. The pointer top points to the first node; an empty stack has top = NULL. There is no overflow except when memory is exhausted, and no space is wasted by a fixed array size.

PUSH(x):

  1. Create a new node p; if memory is not available, report overflow.
  2. p->data = x
  3. p->next = top
  4. top = p

POP:

  1. If top == NULL, report underflow and stop.
  2. p = top; x = p->data
  3. top = top->next
  4. free(p); return x
void push(int x) {
    struct node *p = (struct node*)malloc(sizeof(struct node));
    if (p == NULL) { printf("Overflow\n"); return; }
    p->data = x;
    p->next = top;
    top = p;
}

int pop(void) {
    if (top == NULL) { printf("Underflow\n"); return -1; }
    struct node *p = top;
    int x = p->data;
    top = top->next;
    free(p);
    return x;
}

Both operations are O(1)O(1). For example, pushing 10, 20, 30 gives top -> 30 -> 20 -> 10 -> NULL; a pop returns 30 and top then points to 20.

Circular linked list. In a circular linked list the next pointer of the last node points back to the first node instead of NULL, so the nodes form a ring and there is no node with a NULL link. It may be singly circular (each node has next only) or doubly circular (next and prev, with the last node's next pointing to the first and the first node's prev pointing to the last).

 external pointer
      |
      v
  [10|*]-->[20|*]-->[30|*]
    ^                  |
    |__________________|

Features and advantages:

  • Any node can be reached from any other node, since traversal can start anywhere and continues round the ring.
  • It is convenient to keep a pointer last to the last node; then the first node is last->next, so insertion at both the front and the end takes O(1)O(1) time.
  • It is suitable for round-robin CPU scheduling, a ring of players in a game, and implementing circular queues.
  • Traversal must stop when we return to the starting node (p->next == start) instead of testing for NULL, otherwise it loops forever.

Insertion at the front of a circular list with last pointer:

void insert_front(int x) {
    struct node *p = (struct node*)malloc(sizeof(struct node));
    p->data = x;
    if (last == NULL) {          /* empty list */
        last = p;
        p->next = p;
    } else {
        p->next = last->next;
        last->next = p;
    }
}

Traversal:

void display(void) {
    if (last == NULL) return;
    struct node *p = last->next;
    do {
        printf("%d ", p->data);
        p = p->next;
    } while (p != last->next);
}

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2074 · 10 marks

Illustrate the algorithm for Binary search tree with example.

Answer

A binary search tree (BST) is a binary tree in which, for every node, all keys in the left subtree are smaller than the node's key and all keys in the right subtree are larger (duplicates are not allowed or are handled by a fixed rule). An inorder traversal of a BST gives the keys in sorted order.

Node structure

struct node {
    int info;
    struct node *left, *right;
};

Insertion algorithm

  1. If the tree is empty, make the new node the root.
  2. Otherwise compare the key with the current node. If key << info, go left; if key >> info, go right.
  3. Repeat until a NULL link is found and attach the new node there.
struct node* insert(struct node *root, int key) {
    if (root == NULL) {
        struct node *p = (struct node*)malloc(sizeof(struct node));
        p->info = key; p->left = p->right = NULL;
        return p;
    }
    if (key < root->info)       root->left  = insert(root->left, key);
    else if (key > root->info)  root->right = insert(root->right, key);
    return root;
}

Search algorithm

struct node* search(struct node *root, int key) {
    if (root == NULL || root->info == key) return root;
    if (key < root->info) return search(root->left, key);
    return search(root->right, key);
}

Deletion has three cases:

  1. Node is a leaf: remove it.
  2. Node has one child: replace the node by its child.
  3. Node has two children: replace its key by the inorder successor (smallest key in the right subtree) or inorder predecessor, then delete that node.
struct node* delete(struct node *root, int key) {
    if (root == NULL) return NULL;
    if (key < root->info)      root->left  = delete(root->left, key);
    else if (key > root->info) root->right = delete(root->right, key);
    else {
        if (root->left == NULL)  { struct node *t = root->right; free(root); return t; }
        if (root->right == NULL) { struct node *t = root->left;  free(root); return t; }
        struct node *s = root->right;
        while (s->left != NULL) s = s->left;
        root->info = s->info;
        root->right = delete(root->right, s->info);
    }
    return root;
}

Example. Insert the keys 50, 30, 70, 20, 40, 60, 80 in this order.

  • 50 becomes the root.
  • 30 << 50: left child of 50.
  • 70 >> 50: right child of 50.
  • 20 << 50, << 30: left child of 30.
  • 40 << 50, >> 30: right child of 30.
  • 60 >> 50, << 70: left child of 70.
  • 80 >> 50, >> 70: right child of 70.
        50
      /    \
    30      70
   /  \    /  \
  20  40  60  80

Searching for 60: compare with 50 (go right), with 70 (go left), found 60 after 3 comparisons. Inorder traversal gives 20, 30, 40, 50, 60, 70, 80 (sorted). Deleting 30 (two children) replaces it with its inorder successor 40, leaving 40 with left child 20.

Complexity. Search, insert and delete take O(h)O(h) where hh is the height: O(log⁡n)O(\log n) for a balanced tree and O(n)O(n) in the worst case (a skewed tree from sorted input).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2074 · 10 marks

What do you mean by circular list? Differentiate between stack as a circular list and Queue as a circular list.

Answer

Circular list. A circular list is a linked list in which the last node points back to the first node instead of NULL, so the list forms a ring. Any node can be reached from any other node, and there is no NULL pointer. It may be singly or doubly linked. A single external pointer to the last node gives access to both ends: last->next is the first node.

Stack as a circular list. A stack needs access to only one end (the top). Using a circular list, a single external pointer top/last is kept, and last->next is the top node.

  • Push: new node is inserted after last (at the front of the list), so last->next always refers to the top; the last node's link is updated.
  • Pop: the node after last is deleted.
  • Both operations are done at the same end, in O(1)O(1) time. Order is LIFO.

Queue as a circular list. A queue needs access to both ends. With one pointer rear pointing to the last node, rear->next is the front.

  • Insert (enqueue): a new node is placed after rear and rear is moved to it.
  • Delete (dequeue): the node rear->next (front) is removed.
  • Insertion at the rear and deletion at the front, both O(1)O(1). Order is FIFO.
BasisStack as circular listQueue as circular list
OrderLIFOFIFO
InsertionAt the front, after lastAt the rear, after rear, and rear moves forward
DeletionFrom the front (same end as insertion)From the front (opposite end from insertion)
Pointer movesThe external pointer stays on the last node (except when the stack becomes empty or has one node)rear moves on every insertion
Ends usedOne end onlyBoth ends
Empty conditionlast == NULLrear == NULL
OverflowOnly when memory is exhaustedOnly when memory is exhausted

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2074 · 10 marks

Explain the procedure for construction of Huffman algorithm with example.

Answer

Huffman algorithm is a greedy algorithm that builds an optimal prefix code (variable-length binary codes, no code is a prefix of another) for data compression. Frequent symbols get short codes and rare symbols get long codes.

Procedure

  1. Create a leaf node for each symbol with its frequency, and put all nodes in a priority queue (min-heap) ordered by frequency.
  2. Remove the two nodes with the smallest frequencies.
  3. Create a new internal node whose frequency is their sum, with these two nodes as children, and insert it back into the queue.
  4. Repeat steps 2 and 3 until only one node remains. It is the root of the Huffman tree.
  5. Label every left edge 0 and every right edge 1. The code of a symbol is the sequence of labels from the root to its leaf.

Example. Symbols and frequencies: A = 5, B = 9, C = 12, D = 13, E = 16, F = 45 (total 100).

  • Merge A(5) and B(9) to get N1 = 14.
  • Merge C(12) and D(13) to get N2 = 25.
  • Merge N1(14) and E(16) to get N3 = 30.
  • Merge N2(25) and N3(30) to get N4 = 55.
  • Merge F(45) and N4(55) to get root = 100.
            100
           /    \
        F(45)    55
                /   \
              25     30
             /  \   /  \
          C(12) D(13) 14  E(16)
                     /  \
                  A(5)  B(9)

With left = 0 and right = 1:

SymbolFrequencyCodeLength
F4501
C121003
D131013
A511004
B911014
E161113

Total bits =45(1)+12(3)+13(3)+5(4)+9(4)+16(3)=45+36+39+20+36+48=224= 45(1)+12(3)+13(3)+5(4)+9(4)+16(3) = 45+36+39+20+36+48 = 224.

A fixed 3-bit code would need 3×100=3003\times100=300 bits, so Huffman coding saves 7676 bits (≈25%\approx 25\%).

Decoding is done by reading bits from the root: go left on 0, right on 1, output the symbol on reaching a leaf and restart. With a heap, building the tree takes O(nlog⁡n)O(n\log n).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2074 · 5 marks

Differentiate between structure and union.

Answer

BasisStructureUnion
Keywordstructunion
MemoryEach member gets its own separate memory; size is at least the sum of the member sizes (plus padding)All members share the same memory; size equals the size of the largest member
AccessAll members can be used at the same timeOnly one member holds a valid value at a time; writing one overwrites the others
Value storageEach member keeps its own valueThe last stored value only
UseTo group related data of different types (records)To save memory when only one of several alternatives is needed at a time
InitialisationAny/all members can be initialisedOnly the first member can be initialised at declaration
struct S { int a; float b; char c; };   // size about 4+4+1 (+padding) = 12 bytes
union  U { int a; float b; char c; };   // size 4 bytes

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2074 · 5 marks

Describe the Big ‘O’ notation.

Answer

Big O notation gives an asymptotic upper bound on the growth rate of an algorithm's running time (or space) as the input size nn becomes large. It describes the worst-case order of growth and ignores constants and lower-order terms.

Definition. f(n)=O(g(n))f(n)=O(g(n)) if there exist positive constants cc and n0n_0 such that f(n)≤c g(n)for all n≥n0.f(n)\le c\,g(n)\quad\text{for all } n\ge n_0 .

Example. For f(n)=3n+2f(n)=3n+2: since 3n+2≤4n3n+2\le 4n for all n≥2n\ge 2, we have c=4c=4, n0=2n_0=2, so f(n)=O(n)f(n)=O(n). Similarly 5n2+3n+1=O(n2)5n^2+3n+1=O(n^2).

Common orders (slowest growth to fastest): O(1)<O(log⁡n)<O(n)<O(nlog⁡n)<O(n2)<O(n3)<O(2n)<O(n!)O(1)<O(\log n)<O(n)<O(n\log n)<O(n^2)<O(n^3)<O(2^n)<O(n!)

Examples: array access O(1)O(1), binary search O(log⁡n)O(\log n), linear search O(n)O(n), merge sort O(nlog⁡n)O(n\log n), bubble sort O(n2)O(n^2).

Big O is used to compare algorithms independently of the machine and language.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2074 · 5 marks

Explain the infix to post fix conversion algorithm.

Answer

Infix expressions (operator between operands, e.g. A+BA+B) need precedence and parenthesis rules. Postfix expressions (operator after operands, AB+AB+) do not, so conversion uses a stack to hold operators.

Precedence: ^ (highest, right-associative), then * /, then + -. Parentheses override precedence.

Algorithm

  1. Scan the infix expression from left to right.
  2. If the symbol is an operand, append it to the postfix output.
  3. If it is (, push it on the stack.
  4. If it is ), pop operators from the stack to the output until ( is found; discard both parentheses.
  5. If it is an operator, pop operators from the stack to the output while the top has higher precedence than the scanned operator (or equal precedence for left-associative operators); then push the scanned operator.
  6. After the scan ends, pop all remaining operators to the output.

Example. Convert A+B∗C−DA+B*C-D.

SymbolStackPostfix
AA
++A
B+AB
*+ *AB
C+ *ABC
-- (pop *, then + ; push -)ABC*+
D-ABC*+D
endABC*+D-

Result: ABC∗+D−ABC*+D-. The algorithm runs in O(n)O(n) time.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2074 · 5 marks

Explain the Tower of Hanoi (TOH) with practical example.

Answer

The Tower of Hanoi is a classic recursive puzzle. There are three pegs (source A, auxiliary B, destination C) and nn disks of different sizes stacked on A with the largest at the bottom. The task is to move all disks to C obeying two rules: move only one disk at a time, and never place a larger disk on a smaller one.

Recursive idea

To move nn disks from A to C using B:

  1. Move the top n−1n-1 disks from A to B (using C).
  2. Move the largest disk from A to C.
  3. Move the n−1n-1 disks from B to C (using A).
void toh(int n, char from, char to, char aux) {
    if (n == 0) return;
    toh(n-1, from, aux, to);
    printf("Move disk %d from %c to %c\n", n, from, to);
    toh(n-1, aux, to, from);
}

Example, n=3n=3 (A to C using B), 7 moves:

  1. Disk 1: A to C
  2. Disk 2: A to B
  3. Disk 1: C to B
  4. Disk 3: A to C
  5. Disk 1: B to A
  6. Disk 2: B to C
  7. Disk 1: A to C

Number of moves. T(n)=2T(n−1)+1T(n)=2T(n-1)+1, T(1)=1T(1)=1, giving T(n)=2n−1.T(n)=2^n-1 . For n=3n=3: 23−1=72^3-1=7. The time complexity is O(2n)O(2^n). A practical use is the stack-based nature of recursion, and it is a standard demonstration of how recursion simplifies a problem.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2074 · 5 marks

What do you mean by double linked list? Explain with example.

Answer

A doubly linked list is a linked list in which each node has two pointers: one to the next node and one to the previous node. It can be traversed in both directions.

struct node {
    int info;
    struct node *prev;
    struct node *next;
};
NULL <- [prev|10|next] <-> [prev|20|next] <-> [prev|30|next] -> NULL

Advantages: traversal in both directions; a node can be deleted given only a pointer to it (no need to track the previous node); easy insertion before a node. Disadvantages: extra memory for the second pointer; more pointer updates for each operation.

Example: insert a new node p after node q.

p->prev = q;
p->next = q->next;
if (q->next != NULL)
    q->next->prev = p;
q->next = p;

Example: delete node q.

if (q->prev != NULL) q->prev->next = q->next;
if (q->next != NULL) q->next->prev = q->prev;
free(q);

If the list holds 10, 20, 30 and 25 is inserted after 20, the list becomes 10 <-> 20 <-> 25 <-> 30. Both insertion and deletion at a known position take O(1)O(1).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2074 · 5 marks

What are the types of binary tree? Compare between them.

Answer

A binary tree is a tree in which each node has at most two children (left and right). The main types are:

  1. Strictly (full) binary tree: every node has either 0 or 2 children. A strictly binary tree with nn leaves has 2n−12n-1 nodes.
  2. Complete binary tree: all levels are completely filled except possibly the last, and the last level is filled from left to right. Heaps are complete trees.
  3. Perfect binary tree: all internal nodes have two children and all leaves are at the same level. It has 2h+1−12^{h+1}-1 nodes for height hh.
  4. Skewed binary tree: every node has only a left child (left-skewed) or only a right child (right-skewed); behaves like a linked list.
  5. Binary search tree: left subtree keys << node << right subtree keys.
  6. Balanced tree (AVL): for every node the heights of the left and right subtrees differ by at most 1.
  7. Expression tree: leaves are operands and internal nodes are operators.

Comparison

TypeNodes with childrenShapeHeight for nn nodes
Strictly binary0 or 2Not necessarily level-filledbetween log⁡2n\log_2 n and (n−1)/2(n-1)/2
CompleteFilled left to rightLast level may be partial⌊log⁡2n⌋\lfloor\log_2 n\rfloor
PerfectAll internal nodes have 2All leaves at same levellog⁡2(n+1)−1\log_2(n+1)-1
SkewedEvery node has 1 (except the last)Like a listn−1n-1
BSTAnyOrdered by keylog⁡n\log n to n−1n-1
AVLAnyHeight-balancedO(log⁡n)O(\log n)

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2074 · 5 marks

Differentiate between pre-order traversal and in order traversal.

Answer

Both are depth-first traversals of a binary tree, defined recursively. They differ in when the root (current node) is visited.

BasisPreorderInorder
OrderRoot, Left, Right (NLR)Left, Root, Right (LNR)
Root visitedFirstBetween the left and right subtrees
First node outputThe root of the treeThe leftmost node
Result on a BSTNot sortedKeys in ascending sorted order
UsesCopying a tree, prefix expression of an expression treeSorted output of a BST, infix expression
ReconstructionNeeds inorder also to build a unique treeNeeds preorder or postorder also

Example tree:

      A
     / \
    B   C
   / \
  D   E
  • Preorder: A B D E C
  • Inorder: D B E A C
void preorder(struct node *t) { if (t) { printf("%d ", t->info); preorder(t->left); preorder(t->right); } }
void inorder(struct node *t)  { if (t) { inorder(t->left); printf("%d ", t->info); inorder(t->right); } }

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2074 · 5 marks

What do you mean by sorting? Explain the Bubble sort with example.

Answer

Sorting is the process of arranging the elements of a list in a specified order, ascending or descending (numerically or alphabetically). Sorting makes searching and processing data faster.

Bubble sort. It repeatedly compares adjacent elements and swaps them if they are in the wrong order. After each pass the largest remaining element "bubbles" to its final position at the end. For nn elements, n−1n-1 passes are needed; pass ii compares the first n−in-i pairs. If a pass makes no swap, the list is sorted and the algorithm can stop.

void bubble(int a[], int n) {
    for (int i = 0; i < n-1; i++) {
        int swapped = 0;
        for (int j = 0; j < n-1-i; j++)
            if (a[j] > a[j+1]) {
                int t = a[j]; a[j] = a[j+1]; a[j+1] = t;
                swapped = 1;
            }
        if (!swapped) break;
    }
}

Example. Sort 5, 1, 4, 2, 8.

  • Pass 1: (5,1) swap: 1 5 4 2 8; (5,4) swap: 1 4 5 2 8; (5,2) swap: 1 4 2 5 8; (5,8) no swap. Result 1 4 2 5 8.
  • Pass 2: (1,4) no; (4,2) swap: 1 2 4 5 8; (4,5) no. Result 1 2 4 5 8.
  • Pass 3: no swaps, so the list is sorted: 1 2 4 5 8.

Complexity. Worst and average case O(n2)O(n^2) (about n(n−1)/2n(n-1)/2 comparisons); best case O(n)O(n) with the swap flag; space O(1)O(1); it is stable.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2074 · 5 marks

Differentiate between sequential searching and binary searching.

Answer

BasisSequential (linear) searchBinary search
MethodCompares the key with each element one by one from the startRepeatedly compares the key with the middle element and discards half of the list
Data orderWorks on sorted or unsorted dataRequires sorted data
Data structureArrays and linked listsNeeds random access, so arrays (not suitable for linked lists)
Best caseO(1)O(1)O(1)O(1)
Average/worst caseO(n)O(n)O(log⁡2n)O(\log_2 n)
Speed for large dataSlowVery fast; 1,000,000 items need at most about 20 comparisons
ImplementationVery simpleMore complex
Suitable forSmall or unsorted listsLarge sorted lists

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2074 · 5 marks

Discuss the Kruskal’s algorithm with example.

Answer

Kruskal's algorithm finds a minimum spanning tree (MST) of a connected, weighted, undirected graph using the greedy approach: it repeatedly adds the cheapest edge that does not form a cycle.

Algorithm

  1. Sort all edges in non-decreasing order of weight.
  2. Start with a forest in which each vertex is its own component.
  3. Take the next smallest edge. If its end points lie in different components, add it to the MST and merge the components (checked with union-find); otherwise discard it, since it would form a cycle.
  4. Stop when V−1V-1 edges have been selected.

With sorting, the time complexity is O(Elog⁡E)O(E\log E).

Example. Vertices A, B, C, D, E with edges: B-C = 1, A-C = 2, D-E = 2, A-B = 4, B-D = 5, C-D = 8, C-E = 10.

EdgeWeightDecision
B-C1Accept
A-C2Accept
D-E2Accept
A-B4Reject (A and B already connected through C)
B-D5Accept (joins {A,B,C} with {D,E})

Four edges (V−1=4V-1=4) are selected, so the algorithm stops. MST edges: B-C, A-C, D-E, B-D with total weight 1+2+2+5=101+2+2+5=10.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2075 · 10 marks

How can you use stack to convert an infix expression to postfix? Convert infix expression (A + B)*(C – D) to postfix using stack.

Answer

Infix notation places the operator between its operands and needs precedence and parenthesis rules. Postfix notation places the operator after its operands and needs neither. A stack is used to hold operators (and parentheses) until their operands have been output, which reverses the order of operators according to precedence.

Algorithm

  1. Scan the infix expression from left to right.
  2. If the symbol is an operand, send it directly to the postfix output.
  3. If it is (, push it on the stack.
  4. If it is ), pop operators to the output until ( is on top; pop and discard (.
  5. If it is an operator, while the stack top is an operator of higher or equal precedence (for left-associative operators), pop it to the output; then push the scanned operator.
  6. At the end of the expression, pop all remaining operators to the output.

Precedence: ^ >> *, / >> +, -; ( has the lowest precedence while on the stack.

Conversion of (A+B)∗(C−D)(A+B)*(C-D)

StepSymbolStack (bottom to top)Postfix output
1((
2A(A
3+( +A
4B( +AB
5)(empty)AB+
6**AB+
7(* (AB+
8C* (AB+C
9-* ( -AB+C
10D* ( -AB+CD
11)*AB+CD-
12end(empty)AB+CD-*

The postfix expression is AB+CD−∗AB+CD-*.

Check by evaluation. Let A=2,B=3,C=7,D=4A=2, B=3, C=7, D=4. Infix: (2+3)×(7−4)=15(2+3)\times(7-4)=15. Postfix: push 2, 3; + gives 5; push 7, 4; - gives 3; * gives 5×3=155\times3=15.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2075 · 10 marks

Explain concept of divide and conquer algorithm. Hand test quick algorithm with array of numbers (78, 34, 21, 43, 7, 18, 9, 56, 38, 19).sorting What is time complexity of quick sort algorithm?

Answer

Divide and conquer. It is an algorithm design technique that solves a problem in three steps:

  1. Divide the problem into smaller sub-problems of the same type.
  2. Conquer the sub-problems by solving them recursively (solve directly when small enough).
  3. Combine the solutions of the sub-problems to get the solution of the original problem.

Examples: merge sort, quick sort, binary search, Strassen's matrix multiplication.

Quick sort. Choose a pivot element, partition the array so that elements smaller than the pivot are on its left and larger elements on its right (the pivot is then in its final position), and sort the two parts recursively. The combine step is trivial.

void quick(int a[], int lo, int hi) {
    if (lo >= hi) return;
    int p = a[lo], i = lo + 1, j = hi;
    while (1) {
        while (i <= hi && a[i] <= p) i++;
        while (a[j] > p) j--;
        if (i >= j) break;
        int t = a[i]; a[i] = a[j]; a[j] = t;
    }
    a[lo] = a[j]; a[j] = p;
    quick(a, lo, j-1);
    quick(a, j+1, hi);
}

Hand test on 78, 34, 21, 43, 7, 18, 9, 56, 38, 19 (first element as pivot). Each partition places the pivot in its final position:

Sub-arrayPivotLeft partRight part
78 34 21 43 7 18 9 56 38 197834 21 43 7 18 9 56 38 19 (all smaller)empty
34 21 43 7 18 9 56 38 193421 7 18 9 1943 56 38
21 7 18 9 19217 18 9 19empty
7 18 9 197empty18 9 19
18 9 1918919
43 56 38433856

Combining the pivots and single elements in order gives the sorted array:

7, 9, 18, 19, 21, 34, 38, 43, 56, 78

Time complexity of quick sort

  • Best case (pivot splits the array into equal halves): T(n)=2T(n/2)+O(n)T(n)=2T(n/2)+O(n), giving O(nlog⁡n)O(n\log n).
  • Average case: O(nlog⁡n)O(n\log n).
  • Worst case (already sorted or reverse-sorted input with first/last pivot, as at the first step above): T(n)=T(n−1)+O(n)T(n)=T(n-1)+O(n), giving O(n2)O(n^2).
  • Space: O(log⁡n)O(\log n) on average for the recursion stack.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2075 · 10 marks

Discuss depth first and breadth first traversal of a graph with suitable example.

Answer

Graph traversal visits every vertex reachable from a start vertex exactly once. The two standard methods are depth first search (DFS) and breadth first search (BFS).

Depth first traversal (DFS)

DFS goes as deep as possible along a path before backtracking. It uses a stack (or recursion).

  1. Visit the start vertex, mark it visited and push it.
  2. While the stack is not empty, look at the top vertex; if it has an unvisited neighbour, visit it, mark it and push it; otherwise pop the top vertex (backtrack).
void dfs(int v) {
    visited[v] = 1; printf("%d ", v);
    for (int w = 0; w < n; w++)
        if (adj[v][w] && !visited[w]) dfs(w);
}

Breadth first traversal (BFS)

BFS visits all neighbours of a vertex before moving to the next level. It uses a queue.

  1. Visit the start vertex, mark it and enqueue it.
  2. While the queue is not empty, dequeue a vertex and enqueue all its unvisited neighbours (marking them visited as they are visited).
void bfs(int s) {
    int q[MAX], f = 0, r = 0;
    visited[s] = 1; q[r++] = s;
    while (f < r) {
        int v = q[f++]; printf("%d ", v);
        for (int w = 0; w < n; w++)
            if (adj[v][w] && !visited[w]) { visited[w] = 1; q[r++] = w; }
    }
}

Example. Graph with edges A-B, A-C, B-D, B-E, C-F, E-F. Adjacency lists (alphabetical order): A: B, C; B: A, D, E; C: A, F; D: B; E: B, F; F: C, E.

DFS from A: visit A, go to B, then D (dead end, backtrack to B), then E, then F, then C. DFS order: A B D E F C.

BFS from A: queue A; dequeue A and add B, C; dequeue B and add D, E; dequeue C and add F; then D, E, F have no new neighbours. BFS order: A B C D E F.

Complexity. Both take O(V+E)O(V+E) with adjacency lists and O(V2)O(V^2) with an adjacency matrix. DFS is used for cycle detection, topological sorting and connected components; BFS for shortest paths in unweighted graphs.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2075 · 5 marks

What do you mean by complexity of algorithms? How do you find time complexity?

Answer

Complexity of an algorithm. The complexity of an algorithm measures the resources it needs as a function of the input size nn. There are two kinds:

  • Time complexity: the amount of time (number of basic operations) the algorithm takes.
  • Space complexity: the amount of memory the algorithm uses, including input, auxiliary variables and recursion stack.

It is usually expressed in asymptotic notation: Big O (upper bound), Omega (lower bound) and Theta (tight bound), and analysed for the best, average and worst cases.

Finding time complexity

  1. Choose the basic operation (comparison, assignment, arithmetic) and the input size nn.
  2. Count how many times it executes as a function of nn.
  3. Keep the dominant term and drop constants and lower-order terms.

Rules:

  • A simple statement costs O(1)O(1).
  • A sequence of statements: add the costs, so the maximum dominates.
  • A loop: (cost of the body) ×\times (number of iterations).
  • Nested loops: multiply the iteration counts.
  • A loop where the counter doubles or halves each time runs log⁡2n\log_2 n times.
  • A recursive algorithm gives a recurrence, e.g. T(n)=2T(n/2)+nT(n)=2T(n/2)+n, solved by substitution or the master theorem, giving O(nlog⁡n)O(n\log n).

Examples

for (i = 0; i < n; i++)           // n times
    sum += i;                      // O(n)

for (i = 0; i < n; i++)
    for (j = 0; j < n; j++)       // n * n times
        count++;                   // O(n^2)

for (i = 1; i < n; i *= 2)        // log2 n times
    x++;                           // O(log n)

For the nested loops the operation count is n2n^2, so T(n)=O(n2)T(n)=O(n^2). For a loop with a body that runs 1+2+⋯+n=n(n+1)21+2+\dots+n=\frac{n(n+1)}{2} times, T(n)=O(n2)T(n)=O(n^2).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2075 · 5 marks

Compare stack with queue. How is linear queue different from circular queue?

Answer

Stack vs queue

BasisStackQueue
PrincipleLIFO (last in, first out)FIFO (first in, first out)
Ends usedOne end, the topTwo ends: rear for insertion, front for deletion
Insert operationpushenqueue / insert
Delete operationpopdequeue / delete
PointersOne pointer topTwo pointers front and rear
ApplicationsRecursion, expression evaluation, undo, parenthesis matchingScheduling, buffering, BFS, printer spooling

Linear queue vs circular queue

BasisLinear queueCircular queue
StructureElements are in a straight line; rear only moves forwardThe last position is connected to the first position
Memory useSpace freed at the front by deletions is never reused, so the queue may show "full" (rear == MAX-1) even if empty slots exist at the frontFreed slots are reused by wrapping around
Full conditionrear == MAX-1(rear+1) % MAX == front
Rear updaterear = rear + 1rear = (rear + 1) % MAX
EfficiencyWastefulBetter utilisation of the array
ImplementationSimplerSlightly more complex

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2075 · 5 marks

What is ADT? Discuss stack as an ADT.

Answer

Abstract data type (ADT). An ADT is a mathematical model of a data structure that specifies the data it holds and the operations that can be done on it, together with their behaviour, without saying how they are implemented. The user works only through the interface (information hiding). The same ADT can be implemented with arrays or linked lists. Examples: stack, queue, list, tree.

Stack as an ADT

Data: an ordered collection of elements of one type, with insertion and deletion allowed only at one end, the top. It follows the LIFO principle.

Operations:

OperationDescription
create() / init()Make an empty stack
push(x)Insert element xx at the top; error (overflow) if the stack is full
pop()Remove and return the top element; error (underflow) if empty
peek() / top()Return the top element without removing it
isEmpty()True if the stack has no element
isFull()True if no more elements can be pushed (array implementation)

Axioms: pop(push(S, x)) = S, and peek(push(S, x)) = x.

#define MAX 100
struct stack { int items[MAX]; int top; };   // top = -1 means empty

void push(struct stack *s, int x) {
    if (s->top == MAX-1) printf("Overflow\n");
    else s->items[++s->top] = x;
}
int pop(struct stack *s) {
    if (s->top == -1) { printf("Underflow\n"); return -1; }
    return s->items[s->top--];
}

All operations take O(1)O(1) time. Applications include function calls, expression conversion and evaluation, and undo operations.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2075 · 5 marks

Define recursive algorithm? How do you implement recursive algorithms while writing computer programs?

Answer

Recursive algorithm. A recursive algorithm is one that solves a problem by calling itself on smaller instances of the same problem. It must have:

  1. A base case (stopping condition) that is solved directly.
  2. A recursive case that reduces the problem towards the base case.

Examples: factorial, Fibonacci numbers, Tower of Hanoi, tree traversal.

Implementation in programs. A recursive algorithm is written as a function that calls itself. Each call creates a new activation record (parameters, local variables, return address) on the system call stack. When the base case is reached, calls return one by one, in the reverse order (LIFO).

int fact(int n) {
    if (n == 0) return 1;          // base case
    return n * fact(n - 1);        // recursive case
}

Trace of fact(3): fact(3) calls fact(2), which calls fact(1), which calls fact(0) returning 1. Then fact(1) = 1, fact(2) = 2, fact(3) = 6.

Fibonacci:

int fib(int n) {
    if (n <= 1) return n;
    return fib(n-1) + fib(n-2);
}

Points to remember. Without a reachable base case the recursion never ends (stack overflow). Recursion gives short and clear code but uses extra stack space and function-call overhead; any recursive algorithm can be converted to an iterative one using an explicit stack.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2075 · 5 marks

What are the benefits of using linked list over array? How can you insert a node in a singly linked list?

Answer

Benefits of a linked list over an array

BasisLinked listArray
SizeDynamic, grows and shrinks at run timeFixed at declaration
MemoryAllocated when needed, no wasteMay be wasted or insufficient
Insertion/deletionO(1)O(1) once the position is known; no shifting of elementsO(n)O(n) because elements must be shifted
Memory layoutNodes need not be contiguousNeeds one contiguous block
ExpansionEasyNeeds reallocation and copying

Drawbacks: extra memory for pointers and no direct (random) access, so access to the ii-th element is O(n)O(n).

Inserting a node in a singly linked list

struct node { int info; struct node *next; };

(a) At the beginning:

p = (struct node*)malloc(sizeof(struct node));
p->info = x;
p->next = head;
head = p;

(b) At the end:

p->info = x; p->next = NULL;
if (head == NULL) head = p;
else {
    q = head;
    while (q->next != NULL) q = q->next;
    q->next = p;
}

(c) After a given node q:

p->info = x;
p->next = q->next;
q->next = p;

The order of the last two statements matters: set p->next first, otherwise the rest of the list is lost. Insertion at the beginning or after a given node takes O(1)O(1); at the end it takes O(n)O(n) (without a tail pointer).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2075 · 5 marks

How do you implement binary search algorithm? What is time complexity of this algorithm?

Answer

Binary search. It finds a key in a sorted array by repeatedly comparing the key with the middle element:

  1. Set low = 0, high = n-1.
  2. While low <= high: compute mid = (low + high) / 2.
  3. If a[mid] == key, the search is successful; return mid.
  4. If key < a[mid], set high = mid - 1; otherwise set low = mid + 1.
  5. If the loop ends, the key is not present.
int binsearch(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;
        else if (key < a[mid]) high = mid - 1;
        else low = mid + 1;
    }
    return -1;
}

A recursive version calls binsearch(a, low, mid-1, key) or binsearch(a, mid+1, high, key).

Example. Search 23 in 2, 5, 8, 12, 16, 23, 38, 56 (indices 0 to 7): mid = 3 (12), 23 >> 12 so low = 4; mid = 5 (23), found at index 5.

Time complexity. Each step halves the search range, so the recurrence is T(n)=T(n/2)+1T(n)=T(n/2)+1, which gives T(n)=O(log⁡2n)T(n)=O(\log_2 n) in the worst and average case, and O(1)O(1) in the best case (key at the middle). Space is O(1)O(1) for the iterative version.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2075 · 5 marks

What is hashing? Discuss rehashing with example.

Answer

Hashing. Hashing is a technique for storing and searching data in nearly constant time. A hash function h(k)h(k) maps a key kk to an index of a hash table, e.g. h(k)=k mod mh(k)=k \bmod m for table size mm. When two keys map to the same index, a collision occurs; it is resolved by chaining (linked list at each slot) or open addressing (linear probing, quadratic probing, double hashing). Search, insert and delete take O(1)O(1) on average.

Rehashing. In open addressing, as the table fills, the load factor λ=n/m\lambda = n/m (number of keys / table size) grows, collisions increase and performance falls; insertion may even fail. Rehashing builds a new, larger table (usually about twice the size, rounded up to a prime number), a new hash function with the new size is used, and every existing key is reinserted into the new table. It is done when λ\lambda exceeds a threshold (such as 0.7) or when an insertion fails. Its cost is O(n)O(n) but it happens rarely, so the amortised cost of an insertion stays O(1)O(1).

Example. Table size m=7m=7, h(k)=k mod 7h(k)=k \bmod 7, linear probing. Insert 13, 15, 6, 24, 23.

  • 13 mod 7 = 6, so index 6.
  • 15 mod 7 = 1, so index 1.
  • 6 mod 7 = 6, occupied, so next free index is 0 (wraps around).
  • 24 mod 7 = 3, so index 3.
  • 23 mod 7 = 2, so index 2.
Index0123456
Key615232413

Load factor =5/7≈0.71>0.7=5/7\approx0.71>0.7, so rehash. New size = next prime after 2×7=142\times7=14, that is 17, with h(k)=k mod 17h(k)=k\bmod 17. Reinsert the keys in old table order 6, 15, 23, 24, 13:

  • 6 mod 17 = 6, index 6.
  • 15 mod 17 = 15, index 15.
  • 23 mod 17 = 6, occupied, so index 7.
  • 24 mod 17 = 7, occupied, so index 8.
  • 13 mod 17 = 13, index 13.
Index6781315
Key623241315

Load factor falls to 5/17≈0.295/17\approx0.29, so collisions are reduced.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2075 · 5 marks

How do you transverse a binary tree? Discuss.

Answer

Traversing a binary tree means visiting every node exactly once in some systematic order. Since a tree is not linear, there are several orders. Each is defined recursively in terms of N (visit the node), L (traverse the left subtree) and R (traverse the right subtree).

1. Preorder (N L R): visit the root, traverse the left subtree in preorder, then the right subtree in preorder.

2. Inorder (L N R): traverse the left subtree, visit the root, then traverse the right subtree. For a binary search tree this gives the keys in sorted order.

3. Postorder (L R N): traverse the left subtree, the right subtree, then visit the root.

4. Level order: visit nodes level by level from left to right, using a queue.

void preorder(struct node *t)  { if (t) { printf("%d ", t->info); preorder(t->left); preorder(t->right); } }
void inorder(struct node *t)   { if (t) { inorder(t->left); printf("%d ", t->info); inorder(t->right); } }
void postorder(struct node *t) { if (t) { postorder(t->left); postorder(t->right); printf("%d ", t->info); } }

Example

        A
       / \
      B   C
     / \   \
    D   E   F
  • Preorder: A B D E C F
  • Inorder: D B E A C F
  • Postorder: D E B F C A
  • Level order: A B C D E F

Each traversal visits every node once, so the time is O(n)O(n); the recursion stack needs O(h)O(h) space, where hh is the tree height. Preorder is used to copy a tree, inorder to get sorted output, and postorder to delete a tree or evaluate an expression tree.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2075 · 5 marks

Write short notes on:
  • Dynamic memory allocation
  • Game tree

Answer

(a) Dynamic memory allocation

Dynamic memory allocation is the process of requesting memory from the heap at run time, when the program actually needs it, instead of fixing the size at compile time. The memory can be released when it is no longer needed, so the program uses only as much memory as the data requires.

In C, the functions of <stdlib.h> are used:

  • malloc(size) allocates size bytes (uninitialised) and returns a void *.
  • calloc(n, size) allocates n blocks and initialises them to zero.
  • realloc(ptr, newsize) resizes a previously allocated block.
  • free(ptr) returns the block to the heap.
int *a = (int *)malloc(n * sizeof(int));
if (a == NULL) { /* allocation failed */ }
...
free(a);

It is the basis of linked lists, trees and graphs, where nodes are created and deleted as needed. Advantages are no wastage of memory and flexible size; disadvantages are slower access and the risk of memory leaks and dangling pointers if free is forgotten or misused.

(b) Game tree

A game tree is a tree that represents all possible moves of a two-player game (such as tic-tac-toe or chess). Each node is a game position (state) and each edge is a legal move. The root is the current position; levels alternate between the two players (MAX and MIN). The leaves are terminal positions (win, lose, draw) which are given a score.

To choose the best move, the minimax algorithm is used: at MAX levels the child with the largest value is chosen and at MIN levels the child with the smallest value is chosen, and values are propagated up to the root. Alpha-beta pruning reduces the work by skipping branches that cannot affect the final decision. Since the tree grows exponentially (branching factor bb, depth dd gives about bdb^d nodes), real programs limit the depth and use an evaluation function.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2077 · 10 marks

What is stack? What are the different applications of stack? Explain stack operations with example.

Answer

Stack

A stack is a linear data structure in which insertion and deletion are done at only one end, called the top. It follows the LIFO (Last In First Out) rule: the element inserted last is removed first. Example: a pile of plates.

Applications of stack

  • Function call management and recursion (call stack).
  • Conversion of infix expressions to postfix or prefix.
  • Evaluation of postfix and prefix expressions.
  • Undo/redo in editors; back button in browsers.
  • Checking balanced parentheses.
  • Reversing a string or list.
  • Depth-first search and backtracking (maze, N-queens).

Stack operations

  • push(x): insert element xx at the top. If the stack is full, it is overflow.
  • pop(): remove and return the top element. If the stack is empty, it is underflow.
  • peek()/top(): read the top element without removing it.
  • isEmpty(), isFull(): test the state of the stack.

Array implementation (with top = -1 initially, size MAX):

void push(int x) {
    if (top == MAX - 1) printf("Overflow");
    else s[++top] = x;
}
int pop() {
    if (top == -1) { printf("Underflow"); return -1; }
    return s[top--];
}

Example. Start with an empty stack.

OperationStack (bottom to top)top
push(10)100
push(20)10, 201
push(30)10, 20, 302
pop() returns 3010, 201
peek() returns 2010, 201
pop() returns 20100

Each push and pop takes O(1)O(1) time.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2077 · 10 marks

Differentiate between singly linked list and doubly linked list. How do you insert and delete a node from doubly linked list? Explain.

Answer

Singly vs doubly linked list

Singly linked listDoubly linked list
Each node has data and one pointer (next).Each node has data and two pointers (prev and next).
Traversal only in the forward direction.Traversal in both directions.
Less memory per node.More memory per node (extra pointer).
Deleting a given node needs the previous node, found by traversal (O(n)O(n)).A given node can be deleted in O(1)O(1) using its prev pointer.
Simpler to implement.Insertion and deletion need more pointer updates.

Node structure of a doubly linked list:

struct node {
    int data;
    struct node *prev, *next;
};
struct node *head = NULL;

Insertion

At the beginning:

void insertBeg(int x) {
    struct node *n = malloc(sizeof(struct node));
    n->data = x; n->prev = NULL; n->next = head;
    if (head != NULL) head->prev = n;
    head = n;
}

After a given node p:

void insertAfter(struct node *p, int x) {
    struct node *n = malloc(sizeof(struct node));
    n->data = x;
    n->next = p->next;
    n->prev = p;
    if (p->next != NULL) p->next->prev = n;
    p->next = n;
}

At the end: traverse to the last node t, then set n->prev = t; n->next = NULL; t->next = n; (if the list is empty, head = n).

Deletion

Delete the first node:

void delBeg() {
    if (head == NULL) return;
    struct node *t = head;
    head = head->next;
    if (head != NULL) head->prev = NULL;
    free(t);
}

Delete a given node p:

void delNode(struct node *p) {
    if (p->prev != NULL) p->prev->next = p->next;
    else head = p->next;            /* p was first */
    if (p->next != NULL) p->next->prev = p->prev;
    free(p);
}

Insertion or deletion at a known position takes O(1)O(1) time; finding the position takes O(n)O(n).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2077 · 10 marks

What is shortest path? Explain Dijkstra algorithm for finding shortest path using suitable example.

Answer

Shortest path

In a weighted graph, the shortest path between two vertices is the path whose sum of edge weights is minimum among all paths between them. The single-source shortest path problem finds shortest paths from one source vertex to all other vertices.

Dijkstra's algorithm

It works for graphs with non-negative edge weights and uses a greedy strategy: repeatedly pick the unvisited vertex with the smallest known distance and relax its outgoing edges.

  1. Set dist[source] = 0 and dist[v] = infinity for all other vertices; mark all vertices unvisited.
  2. Select the unvisited vertex uu with the smallest dist; mark it visited.
  3. For each neighbour vv of uu: if dist[u]+w(u,v)<dist[v]dist[u] + w(u,v) < dist[v], then set dist[v]=dist[u]+w(u,v)dist[v] = dist[u] + w(u,v) and parent[v] = u.
  4. Repeat steps 2 and 3 until all vertices are visited.
Dijkstra(G, s):
    for each v: dist[v] = INF, visited[v] = false
    dist[s] = 0
    repeat n times:
        u = unvisited vertex with minimum dist
        visited[u] = true
        for each neighbour v of u:
            if dist[u] + w(u,v) < dist[v]:
                dist[v] = dist[u] + w(u,v); parent[v] = u

Time complexity is O(V2)O(V^2) with an array, and O((V+E)log⁡V)O((V+E)\log V) with a min-heap.

Example. Edges: A-B = 4, A-C = 2, B-C = 1, B-D = 5, C-D = 8, C-E = 10, D-E = 2 (undirected). Source = A.

StepVertex chosenABCDE
Init-0infinfinfinf
1A (0)042infinf
2C (2)03 (via C: 2+1)21012
3B (3)0328 (3+5)12
4D (8)032810 (8+2)
5E (10)032810

Shortest distances from A: B = 3, C = 2, D = 8, E = 10. The paths are A-C-B (3), A-C (2), A-C-B-D (8) and A-C-B-D-E (10).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2077 · 10 marks

What is dynamic memory allocation? Compare data structure with abstract data type.

Answer

Dynamic memory allocation

Dynamic memory allocation means obtaining memory from the heap at run time as required and releasing it when it is no longer needed. In C it is done using malloc(), calloc(), realloc() and free().

int *p = (int *)malloc(5 * sizeof(int));  /* space for 5 integers */
p = (int *)realloc(p, 10 * sizeof(int));  /* grow to 10 */
free(p);                                  /* release */

Compared with static allocation (fixed at compile time, e.g. int a[5];), it avoids wasting memory, allows structures such as linked lists and trees to grow and shrink, and gives the programmer control over lifetime. The price is slower allocation and the risk of memory leaks and dangling pointers.

Data structure vs abstract data type (ADT)

An ADT is a mathematical/logical model that specifies a set of data and the operations on it, without saying how they are implemented (for example Stack, Queue, List). A data structure is the concrete implementation of that model in a programming language, with actual storage and algorithms (for example a stack implemented using an array or a linked list).

Abstract data typeData structure
Logical view: what operations are done.Implementation view: how they are done.
Independent of any programming language.Written in a specific programming language.
Defines data values and operations only.Defines storage organisation and code for operations.
Example: Stack ADT with push, pop.Example: array-based or linked stack.
One ADT can have many implementations.A data structure implements one or more ADTs.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2077 · 10 marks

Explain algorithm for evaluation of postfix expression using stack

Answer

Evaluation of a postfix expression using a stack

In postfix (reverse Polish) notation the operator comes after its operands, e.g. a b +. No parentheses or precedence rules are needed, so the expression can be evaluated in one left-to-right scan with a stack of operands.

Algorithm

  1. Create an empty stack.
  2. Scan the expression from left to right, one symbol at a time.
  3. If the symbol is an operand, push its value onto the stack.
  4. If the symbol is an operator, pop two values: first pop gives op2op_2 (the right operand) and second pop gives op1op_1 (the left operand). Compute op1  operator  op2op_1 \;\text{operator}\; op_2 and push the result.
  5. After the whole expression is scanned, the single value left on the stack is the result.
evalPostfix(P):
    for each symbol ch in P:
        if ch is operand: push(value(ch))
        else:
            b = pop(); a = pop()
            push(a ch b)
    return pop()

The order matters for non-commutative operators (−-, //, ∧\wedge): the second popped value is the left operand.

Example. Evaluate 5 6 2 + * 12 4 / -.

SymbolActionStack
5push5
6push5, 6
2push5, 6, 2
+6 + 2 = 85, 8
*5 * 8 = 4040
12push40, 12
4push40, 12, 4
/12 / 4 = 340, 3
-40 - 3 = 3737

Result =37= 37. Time complexity is O(n)O(n) for an expression of nn symbols.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2077 · 10 marks

Explain queue as an ADT.

Answer

Queue as an ADT

A queue is a linear collection in which insertion takes place at one end (rear) and deletion at the other end (front). It follows FIFO (First In First Out). As an abstract data type, it is defined by its data and operations, independent of implementation.

ADT specification

Data: an ordered collection of elements with a front and a rear.

Operations:

  • create(): make an empty queue.
  • enqueue(x): insert xx at the rear. Precondition: queue not full.
  • dequeue(): remove and return the front element. Precondition: queue not empty.
  • front(): return the front element without removing it.
  • isEmpty(): true if the queue has no element.
  • isFull(): true if no more elements can be added (bounded implementation).

Array implementation (linear queue)

#define MAX 100
int q[MAX], front = 0, rear = -1;

void enqueue(int x) {
    if (rear == MAX - 1) printf("Overflow");
    else q[++rear] = x;
}
int dequeue() {
    if (front > rear) { printf("Underflow"); return -1; }
    return q[front++];
}

Queue is empty when front > rear. A drawback is that freed positions at the front are not reused; a circular queue (using (rear+1) % MAX) removes this problem.

Linked implementation: enqueue adds a node at the tail and dequeue removes the head node; no fixed size limit.

Each operation takes O(1)O(1) time.

Types: simple queue, circular queue, double-ended queue (deque) and priority queue.

Applications: CPU/job scheduling, printer spooling, buffering in I/O, breadth-first search, call centre waiting lines.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2077 · 10 marks

Write a recursive program to find GCD of two numbers.

Answer

Recursive GCD (Euclid's algorithm)

The GCD of two numbers aa and bb satisfies

gcd⁡(a,b)={aif b=0gcd⁡(b,  a mod b)otherwise\gcd(a,b)=\begin{cases} a & \text{if } b=0\\ \gcd(b,\; a \bmod b) & \text{otherwise}\end{cases}

The base case is b=0b = 0, and each call reduces bb, so the recursion terminates.

#include <stdio.h>

int gcd(int a, int b) {
    if (b == 0)
        return a;
    return gcd(b, a % b);
}

int main() {
    int x, y;
    printf("Enter two numbers: ");
    scanf("%d %d", &x, &y);
    printf("GCD of %d and %d = %d\n", x, y, gcd(x, y));
    return 0;
}

Trace for gcd(48, 18):

  • gcd(48, 18) calls gcd(18, 12) since 48 mod 18=1248 \bmod 18 = 12
  • gcd(18, 12) calls gcd(12, 6) since 18 mod 12=618 \bmod 12 = 6
  • gcd(12, 6) calls gcd(6, 0) since 12 mod 6=012 \bmod 6 = 0
  • gcd(6, 0) returns 6

So gcd⁡(48,18)=6\gcd(48,18)=6. The time complexity is O(log⁡(min⁡(a,b)))O(\log(\min(a,b))).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2077 · 10 marks

What is linked list? How is it different from array?

Answer

Linked list

A linked list is a linear data structure made of nodes. Each node has a data field and a link (pointer) to the next node; the last node points to NULL. A pointer head holds the address of the first node. Nodes are created dynamically and are not stored in contiguous memory.

struct node {
    int data;
    struct node *next;
};

Types: singly linked list, doubly linked list and circular linked list.

Difference between linked list and array

ArrayLinked list
Elements stored in contiguous memory.Nodes may be anywhere in memory, connected by pointers.
Size is fixed at declaration (static).Size grows and shrinks at run time (dynamic).
Direct (random) access by index in O(1)O(1).Sequential access only; reaching the kk-th node takes O(k)O(k).
Insertion/deletion in the middle needs shifting, O(n)O(n).Insertion/deletion needs only pointer changes, O(1)O(1) once the position is known.
No extra memory for links.Extra memory for the pointer in each node.
Memory may be wasted (unused slots) or insufficient.Memory is allocated as needed, no wastage.
Better cache performance.Poorer cache performance.

Arrays suit situations with frequent index access and fixed size; linked lists suit frequent insertions and deletions and unknown size.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2077 · 10 marks

Hand test bubble sort with array of numbers 53, 42, 78, 3, 5, 2, 15 in ascending order.

Answer

Bubble sort

Bubble sort compares adjacent elements and swaps them if they are out of order. After each pass the largest remaining element moves ("bubbles") to its final position at the right end.

Array: 53, 42, 78, 3, 5, 2, 15 (ascending order).

Pass 1

  • 53 > 42, swap: 42, 53, 78, 3, 5, 2, 15
  • 53 < 78, no swap
  • 78 > 3, swap: 42, 53, 3, 78, 5, 2, 15
  • 78 > 5, swap: 42, 53, 3, 5, 78, 2, 15
  • 78 > 2, swap: 42, 53, 3, 5, 2, 78, 15
  • 78 > 15, swap: 42, 53, 3, 5, 2, 15, 78

Pass 2

  • 42 < 53, no swap
  • 53 > 3, swap: 42, 3, 53, 5, 2, 15, 78
  • 53 > 5, swap: 42, 3, 5, 53, 2, 15, 78
  • 53 > 2, swap: 42, 3, 5, 2, 53, 15, 78
  • 53 > 15, swap: 42, 3, 5, 2, 15, 53, 78

Pass 3

  • 42 > 3, swap: 3, 42, 5, 2, 15, 53, 78
  • 42 > 5, swap: 3, 5, 42, 2, 15, 53, 78
  • 42 > 2, swap: 3, 5, 2, 42, 15, 53, 78
  • 42 > 15, swap: 3, 5, 2, 15, 42, 53, 78

Pass 4

  • 3 < 5, no swap
  • 5 > 2, swap: 3, 2, 5, 15, 42, 53, 78
  • 5 < 15, 15 < 42: no swap

Result: 3, 2, 5, 15, 42, 53, 78

Pass 5

  • 3 > 2, swap: 2, 3, 5, 15, 42, 53, 78
  • remaining comparisons need no swap.

Pass 6: no swap occurs, so the array is sorted.

Sorted array: 2, 3, 5, 15, 42, 53, 78

Time complexity is O(n2)O(n^2) in the worst and average case; with a "swapped" flag the best case is O(n)O(n).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2077 · 10 marks

What is hashing? Explain concept of hash table and hash function with example.

Answer

Hashing

Hashing is a technique to store and retrieve data directly using a key, by converting the key into an array index with a hash function. It gives average search, insertion and deletion time of O(1)O(1).

Hash table

A hash table is an array of mm slots (buckets) in which each record is stored at the index computed from its key. The index of key kk is h(k)h(k).

Hash function

A hash function hh maps a key to an index in 0,…,m−10,\dots,m-1. A good hash function is quick to compute, distributes keys uniformly and minimises collisions. Common methods:

  • Division method: h(k)=k mod mh(k) = k \bmod m (choose mm prime).
  • Mid-square method: square the key and take the middle digits.
  • Folding method: split the key into parts and add them, then take mod mm.

Example. Table size m=10m = 10, hash function h(k)=k mod 10h(k) = k \bmod 10. Insert keys 25, 42, 17, 38.

Keyh(k)h(k)Index
2525 mod 10=525 \bmod 10 = 55
4242 mod 10=242 \bmod 10 = 22
1717 mod 10=717 \bmod 10 = 77
3838 mod 10=838 \bmod 10 = 88

Table: index 2 holds 42, index 5 holds 25, index 7 holds 17, index 8 holds 38. To search 17, compute h(17)=7h(17)=7 and check index 7 directly.

If a key such as 35 is inserted, h(35)=5h(35)=5 is already occupied by 25. This is a collision, which is handled by collision resolution techniques such as chaining or open addressing.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2077 · 10 marks

What is minimum spanning tree? Explain

Answer

Minimum spanning tree (MST)

A spanning tree of a connected, undirected graph with VV vertices is a subgraph that includes all vertices, is connected and has no cycle; it has exactly V−1V - 1 edges. For a weighted graph, the minimum spanning tree is the spanning tree whose total edge weight is the smallest. Applications: laying cable, road, pipeline and network design.

Two standard algorithms are Kruskal's and Prim's.

Kruskal's algorithm (greedy on edges)

  1. Sort all edges in non-decreasing order of weight.
  2. Take the next smallest edge; add it if it does not form a cycle with the edges already chosen (check using union-find), else discard it.
  3. Stop when V−1V - 1 edges are chosen.

Prim's algorithm (greedy on vertices)

  1. Start with any vertex in the tree.
  2. Repeatedly choose the minimum-weight edge connecting a tree vertex to a vertex outside the tree and add it.
  3. Stop when all vertices are in the tree.

Example. Edges: A-B = 4, A-C = 2, B-C = 1, B-D = 5, C-D = 8, C-E = 10, D-E = 2.

Kruskal: sorted edges B-C (1), A-C (2), D-E (2), A-B (4), B-D (5), C-D (8), C-E (10).

EdgeWeightDecision
B-C1accept
A-C2accept
D-E2accept
A-B4reject (A, B, C already connected, forms a cycle)
B-D5accept (joins {A,B,C} with {D,E})

Four edges (V−1=4V - 1 = 4) are chosen: B-C, A-C, D-E, B-D. Total weight =1+2+2+5=10= 1 + 2 + 2 + 5 = 10.

Complexity: Kruskal O(Elog⁡E)O(E \log E); Prim O(V2)O(V^2) with an array, or O(Elog⁡V)O(E\log V) with a heap.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2077 · 10 marks

Write short notes on:
  • Tail recursion
  • Collision resolution techniques

Answer

(a) Tail recursion

A recursive function is tail recursive if the recursive call is the very last action performed in the function: nothing remains to be done after the call returns (no multiplication, addition etc. on its result). Because the current stack frame is not needed after the call, a compiler can reuse it (tail-call optimisation), converting the recursion into a loop and using O(1)O(1) stack space.

Non-tail recursive factorial (multiplication happens after the call):

int fact(int n) {
    if (n <= 1) return 1;
    return n * fact(n - 1);
}

Tail recursive factorial (using an accumulator):

int fact(int n, int acc) {
    if (n <= 1) return acc;
    return fact(n - 1, n * acc);   /* last action is the call */
}

The tail version is called as fact(5, 1). Tail recursion is easy to convert to iteration and avoids stack overflow for deep recursion.

(b) Collision resolution techniques

A collision occurs when two different keys hash to the same index. The two main families of resolution are:

1. Separate chaining (open hashing). Each table slot holds a linked list of all keys that hash to that slot. A colliding key is simply added to the list. Example with h(k)=k mod 10h(k)=k \bmod 10: keys 25 and 35 both go to slot 5, so slot 5 holds the list 25 -> 35. Table never overflows and deletion is easy, but extra memory is used for pointers and search can degrade to O(n)O(n) if lists grow long.

2. Open addressing (closed hashing). All keys are stored inside the table itself; on a collision another empty slot is searched by a probe sequence.

  • Linear probing: try (h(k)+i) mod m(h(k)+i) \bmod m for i=0,1,2,…i = 0,1,2,\dots. Simple, but causes primary clustering.
  • Quadratic probing: try (h(k)+i2) mod m(h(k)+i^2) \bmod m. Reduces primary clustering but causes secondary clustering.
  • Double hashing: try (h1(k)+i h2(k)) mod m(h_1(k)+i\,h_2(k)) \bmod m using a second hash function. Gives the best distribution.

Example (linear probing, m=10m=10): insert 25 at index 5; inserting 35 finds index 5 occupied, so it goes to index 6.

Another approach is rehashing, i.e. growing the table and re-inserting all keys when the load factor becomes high.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2078 · 10 marks

Define Queue. Write are different applications of queue? Explain queue operations with example.

Answer

Queue

A queue is a linear data structure in which elements are inserted at one end (rear) and deleted from the other end (front). It follows FIFO (First In First Out): the element inserted first is removed first, like people waiting in a line at a ticket counter.

Applications of queue

  • CPU process scheduling and job scheduling.
  • Printer spooling and other I/O buffering.
  • Breadth-first traversal of graphs and trees.
  • Handling requests in web servers and call centres.
  • Simulation of real-life waiting lines (bank, traffic).
  • Data transfer between asynchronous processes (keyboard buffer, pipes).

Queue operations

  • enqueue(x): add xx at the rear (overflow if full).
  • dequeue(): remove and return the front element (underflow if empty).
  • front(): look at the front element without removing it.
  • isEmpty(), isFull().
#define MAX 5
int q[MAX], front = 0, rear = -1;

void enqueue(int x) {
    if (rear == MAX - 1) printf("Overflow");
    else q[++rear] = x;
}
int dequeue() {
    if (front > rear) { printf("Underflow"); return -1; }
    return q[front++];
}

Example. Start with an empty queue.

OperationQueue (front to rear)
enqueue(10)10
enqueue(20)10, 20
enqueue(30)10, 20, 30
dequeue() returns 1020, 30
enqueue(40)20, 30, 40
dequeue() returns 2030, 40

Each operation takes O(1)O(1) time.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2078 · 10 marks

Explain circular linked list with example. How do you implement linked list operation in singly linked list? Explain.

Answer

Circular linked list

In a circular linked list the pointer of the last node points back to the first node instead of NULL, so the nodes form a ring. It can be singly or doubly linked. Any node can be a starting point, and the whole list can be traversed from any node. It is useful for round-robin scheduling and for implementing circular queues.

Example: with nodes 10, 20, 30, the links are 10 -> 20 -> 30 -> back to 10. An empty list has head == NULL; a one-node list has head->next == head.

Operations on a singly linked list

struct node { int data; struct node *next; };
struct node *head = NULL;

1. Traversal

void display() {
    struct node *t = head;
    while (t != NULL) { printf("%d ", t->data); t = t->next; }
}

2. Insertion

At the beginning:

void insertBeg(int x) {
    struct node *n = malloc(sizeof(struct node));
    n->data = x; n->next = head; head = n;
}

At the end:

void insertEnd(int x) {
    struct node *n = malloc(sizeof(struct node)), *t = head;
    n->data = x; n->next = NULL;
    if (head == NULL) { head = n; return; }
    while (t->next != NULL) t = t->next;
    t->next = n;
}

After a given node p: n->next = p->next; p->next = n;

3. Deletion

First node:

void delBeg() {
    if (head == NULL) return;
    struct node *t = head; head = head->next; free(t);
}

A node with value xx:

void delValue(int x) {
    struct node *t = head, *prev = NULL;
    while (t != NULL && t->data != x) { prev = t; t = t->next; }
    if (t == NULL) return;              /* not found */
    if (prev == NULL) head = t->next;   /* first node */
    else prev->next = t->next;
    free(t);
}

4. Search

struct node *search(int x) {
    for (struct node *t = head; t != NULL; t = t->next)
        if (t->data == x) return t;
    return NULL;
}

Insertion/deletion at the beginning take O(1)O(1); at the end, search and general deletion take O(n)O(n).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2078 · 10 marks

What is binary search tree? Write a program to implement insertion and deletion algorithms in binary search tree.

Answer

Binary search tree (BST)

A binary search tree is a binary tree in which, for every node, all keys in the left subtree are smaller than the node's key and all keys in the right subtree are greater (duplicates are not allowed). An inorder traversal of a BST gives the keys in sorted order. Search, insertion and deletion take O(h)O(h) time, where hh is the height (O(log⁡n)O(\log n) for a balanced tree, O(n)O(n) for a skewed one).

Program

#include <stdio.h>
#include <stdlib.h>

struct node {
    int key;
    struct node *left, *right;
};

struct node *newNode(int k) {
    struct node *n = (struct node *)malloc(sizeof(struct node));
    n->key = k; n->left = n->right = NULL;
    return n;
}

/* insertion */
struct node *insert(struct node *root, int k) {
    if (root == NULL) return newNode(k);
    if (k < root->key)      root->left  = insert(root->left, k);
    else if (k > root->key) root->right = insert(root->right, k);
    return root;
}

struct node *minNode(struct node *t) {
    while (t->left != NULL) t = t->left;
    return t;
}

/* deletion */
struct node *delete(struct node *root, int k) {
    if (root == NULL) return NULL;
    if (k < root->key)
        root->left = delete(root->left, k);
    else if (k > root->key)
        root->right = delete(root->right, k);
    else {
        if (root->left == NULL) {            /* 0 or 1 child (right) */
            struct node *t = root->right;
            free(root);
            return t;
        }
        if (root->right == NULL) {           /* 1 child (left) */
            struct node *t = root->left;
            free(root);
            return t;
        }
        struct node *s = minNode(root->right);   /* inorder successor */
        root->key = s->key;
        root->right = delete(root->right, s->key);
    }
    return root;
}

void inorder(struct node *r) {
    if (r) { inorder(r->left); printf("%d ", r->key); inorder(r->right); }
}

int main() {
    struct node *root = NULL;
    int a[] = {50, 30, 70, 20, 40, 60, 80};
    for (int i = 0; i < 7; i++) root = insert(root, a[i]);
    inorder(root);  printf("\n");      /* 20 30 40 50 60 70 80 */
    root = delete(root, 20);           /* leaf */
    root = delete(root, 30);           /* one child */
    root = delete(root, 50);           /* two children */
    inorder(root);  printf("\n");      /* 40 60 70 80 */
    return 0;
}

Explanation

Insertion: move left or right by comparing the key with the node until a NULL position is reached, and attach the new node there.

Deletion has three cases:

  1. Node is a leaf: remove it.
  2. Node has one child: replace the node by its child.
  3. Node has two children: copy the inorder successor (smallest key of the right subtree) into the node, then delete that successor from the right subtree.

In the sample run, deleting 20 (leaf), then 30 (one child, 40 takes its place), then 50 (two children, replaced by 60) leaves the inorder sequence 40 60 70 80.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2078 · 5 marks

How do you find complexity of algorithms? Explain

Answer

Complexity of algorithms

The complexity of an algorithm measures the resources it needs as a function of the input size nn. There are two kinds:

  • Time complexity: the number of basic steps (comparisons, assignments, arithmetic operations) executed.
  • Space complexity: the amount of memory needed (input plus auxiliary variables, stack).

How to find it

  1. Choose the input size nn and decide the basic operation to count.
  2. Count how many times each statement is executed, as a function of nn.
  3. Add the counts to get T(n)T(n).
  4. Keep only the dominant (highest-order) term and drop constants; express using asymptotic notation.

Rules of thumb: a simple statement is O(1)O(1); a loop running nn times is O(n)O(n); nested loops multiply, e.g. two nested loops to nn give O(n2)O(n^2); a loop where the variable is halved or doubled each time is O(log⁡n)O(\log n); consecutive blocks add, so the larger one dominates; for recursion, write a recurrence such as T(n)=2T(n/2)+nT(n)=2T(n/2)+n and solve it (here O(nlog⁡n)O(n\log n)).

Example.

for (i = 0; i < n; i++)        /* n+1 tests */
    for (j = 0; j < n; j++)    /* n(n+1) tests */
        sum = sum + a[i][j];   /* n*n times */

T(n)≈n2+lower termsT(n) \approx n^2 + \text{lower terms}, so the time complexity is O(n2)O(n^2).

Asymptotic notations

  • Big-O O(g(n))O(g(n)): upper bound (worst case).
  • Big-Omega Ω(g(n))\Omega(g(n)): lower bound (best case).
  • Big-Theta Θ(g(n))\Theta(g(n)): tight bound.

Algorithms are analysed for best, average and worst cases; for example linear search is O(1)O(1) best case and O(n)O(n) worst case.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2078 · 5 marks

Evaluate the expression ABCD-x+ using stack where A=5, B=4, C=3 and D=7

Answer

Postfix expression ABCD-x+ with A = 5, B = 4, C = 3, D = 7 becomes 5 4 3 7 - x +.

Scan left to right; push operands; for an operator pop the right operand first, then the left operand.

SymbolActionStack (bottom to top)
A (5)push5
B (4)push5, 4
C (3)push5, 4, 3
D (7)push5, 4, 3, 7
-pop 7 and 3; compute 3−7=−43 - 7 = -4; push5, 4, -4
xpop -4 and 4; compute 4×(−4)=−164 \times (-4) = -16; push5, -16
+pop -16 and 5; compute 5+(−16)=−115 + (-16) = -11; push-11

The stack contains one value, so the result is -11.

This equals the infix expression A+B×(C−D)=5+4×(3−7)=5−16=−11A + B \times (C - D) = 5 + 4\times(3-7) = 5 - 16 = -11.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2078 · 5 marks

What is priority queue? Why do you need this type of queue?

Answer

Priority queue

A priority queue is a queue in which every element has a priority, and the element with the highest priority (or lowest, depending on the convention) is served first, regardless of the order of arrival. Elements of equal priority are served in FIFO order.

Operations: insert(x, priority) adds an element, deleteMax()/deleteMin() removes the element with the highest/lowest priority, and peek() reads it. It can be implemented with an ordered or unordered array/list (O(n)O(n) for insert or delete) or, most efficiently, with a binary heap (O(log⁡n)O(\log n) for both).

Example: insert (task A, 2), (task B, 5), (task C, 1). With the largest number meaning highest priority, the removal order is B, A, C, whatever the insertion order.

Why it is needed

An ordinary queue serves strictly in arrival order, which is unsuitable when some items are more urgent. Priority queues are required in:

  • CPU scheduling, where system processes get priority over user processes.
  • Emergency handling, e.g. hospital patients by severity.
  • Dijkstra's shortest path and Prim's MST algorithms (pick the minimum-distance vertex).
  • Huffman coding (repeatedly take the two lowest-frequency nodes).
  • Network packet scheduling and event-driven simulation.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2078 · 5 marks

Write a recursive program to find nth fibonacci number.

Answer

Recursive program for the nth Fibonacci number

The Fibonacci sequence is 0, 1, 1, 2, 3, 5, 8, ... defined by

F(n)={nn=0 or 1F(n−1)+F(n−2)n≥2F(n)=\begin{cases} n & n = 0 \text{ or } 1\\ F(n-1)+F(n-2) & n \ge 2\end{cases}

#include <stdio.h>

int fib(int n) {
    if (n == 0 || n == 1)      /* base cases */
        return n;
    return fib(n - 1) + fib(n - 2);
}

int main() {
    int n;
    printf("Enter n: ");
    scanf("%d", &n);
    printf("Fibonacci(%d) = %d\n", n, fib(n));
    return 0;
}

For n=5n = 5: F(5)=F(4)+F(3)=3+2=5F(5)=F(4)+F(3)=3+2=5. The sequence is 0, 1, 1, 2, 3, 5, so the 5th term (counting from F(0)=0F(0)=0) is 5.

This version recomputes the same values many times, so its time complexity is exponential, about O(2n)O(2^n), while stack depth is O(n)O(n). It can be improved with memoisation or iteration to O(n)O(n).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2078 · 5 marks

Explain array implementation of list.

Answer

Array implementation of a list

A list is an ordered collection of elements a1,a2,…,ana_1, a_2, \dots, a_n. In the array (static/sequential) implementation the elements are stored in consecutive memory locations of an array, and a variable n (or last) records the current number of elements. The ii-th element is at index i−1i-1 and can be reached in O(1)O(1) time.

#define MAX 100
int list[MAX];
int n = 0;                       /* number of elements */

Insertion at position pospos (0-based): check that the array is not full, shift elements from pospos to the end one place to the right, place the new item, and increase n.

void insert(int pos, int x) {
    if (n == MAX) { printf("List full"); return; }
    for (int i = n - 1; i >= pos; i--)
        list[i + 1] = list[i];
    list[pos] = x;
    n++;
}

Deletion at position pospos: shift elements after pospos one place to the left and decrease n.

void delete(int pos) {
    if (pos < 0 || pos >= n) { printf("Invalid"); return; }
    for (int i = pos; i < n - 1; i++)
        list[i] = list[i + 1];
    n--;
}

Traversal and search scan the array from index 0 to n−1n-1, taking O(n)O(n).

Complexity: access O(1)O(1); insertion and deletion O(n)O(n) because of shifting (at the end, O(1)O(1)).

Advantages: simple, fast random access, no pointer overhead. Disadvantages: fixed maximum size, wasted space if not full, and costly insertions and deletions.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2078 · 5 marks

Hand test selection sort with array of numbers 4, 71, 32, 19, 61, 2, -5 in descending order.

Answer

Selection sort (descending order)

In each pass, find the largest element in the unsorted part and swap it with the first element of that part.

Array: 4, 71, 32, 19, 61, 2, -5

PassUnsorted part searchedLargestSwapArray after pass
14, 71, 32, 19, 61, 2, -571with position 1 (value 4)71, 4, 32, 19, 61, 2, -5
24, 32, 19, 61, 2, -561with position 2 (value 4)71, 61, 32, 19, 4, 2, -5
332, 19, 4, 2, -532already in place71, 61, 32, 19, 4, 2, -5
419, 4, 2, -519already in place71, 61, 32, 19, 4, 2, -5
54, 2, -54already in place71, 61, 32, 19, 4, 2, -5
62, -52already in place71, 61, 32, 19, 4, 2, -5

The last element -5 is then automatically in place.

Sorted array in descending order: 71, 61, 32, 19, 4, 2, -5

Number of comparisons is n(n−1)/2=21n(n-1)/2 = 21; time complexity O(n2)O(n^2) in all cases.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2078 · 5 marks

Write a program to implement sequential search algorithm.

Answer

Sequential (linear) search

Sequential search examines the elements of a list one by one from the first, comparing each with the key, until a match is found or the list ends.

#include <stdio.h>

int seqSearch(int a[], int n, int key) {
    for (int i = 0; i < n; i++)
        if (a[i] == key)
            return i;        /* found at index i */
    return -1;               /* not found */
}

int main() {
    int a[100], n, key, i, pos;
    printf("Enter number of elements: ");
    scanf("%d", &n);
    printf("Enter %d elements: ", n);
    for (i = 0; i < n; i++)
        scanf("%d", &a[i]);
    printf("Enter element to search: ");
    scanf("%d", &key);

    pos = seqSearch(a, n, key);
    if (pos == -1)
        printf("%d not found\n", key);
    else
        printf("%d found at position %d\n", key, pos + 1);
    return 0;
}

Complexity: best case O(1)O(1) (key is first), worst and average case O(n)O(n). It does not need the list to be sorted, and works for arrays and linked lists.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2078 · 5 marks

What is graph traversal? Explain.

Answer

Graph traversal

Graph traversal means visiting every vertex of a graph exactly once in a systematic way, starting from a given source vertex. A visited array is used so that a vertex is not processed twice (graphs may contain cycles). The two standard methods are breadth-first search and depth-first search.

1. Breadth-First Search (BFS)

Visits all vertices at distance 1 from the source, then distance 2, and so on, using a queue.

  1. Mark the source visited and enqueue it.
  2. Dequeue a vertex uu, process it, and enqueue all its unvisited neighbours (marking them visited).
  3. Repeat until the queue is empty.

2. Depth-First Search (DFS)

Goes as deep as possible along a path before backtracking, using a stack (or recursion).

  1. Mark the source visited and push it.
  2. Visit an unvisited neighbour of the top vertex and push it; if there is none, pop (backtrack).
  3. Repeat until the stack is empty.

Example. Edges: A-B, A-C, B-D, C-D, D-E. Start at A (neighbours taken alphabetically).

  • BFS: A, B, C, D, E
  • DFS: A, B, D, C, E (A to B to D, then D's unvisited neighbour C, then back to D to E)

Both take O(V+E)O(V+E) time with an adjacency list. Uses: finding connected components, shortest path in unweighted graphs (BFS), cycle detection, topological sorting (DFS), and solving mazes.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2078 · 5 marks

Write short notes on:
  • Divide and Conquer sorting
  • AVL Tree

Answer

(a) Divide and conquer sorting

Divide and conquer solves a problem in three steps: divide it into smaller subproblems, conquer them by solving recursively (a very small problem is solved directly), and combine the sub-solutions into the final answer. Sorting algorithms based on it are merge sort and quick sort.

Merge sort: divide the array into two halves, sort each half recursively, then merge the two sorted halves into one sorted array. Work is in the combine step. Recurrence T(n)=2T(n/2)+O(n)T(n)=2T(n/2)+O(n) gives O(nlog⁡n)O(n\log n) in all cases, with O(n)O(n) extra space; it is stable.

Quick sort: choose a pivot, partition the array so that smaller elements are on its left and larger elements on its right, then sort both parts recursively. Work is in the divide step; no combine step is needed. Average time O(nlog⁡n)O(n\log n), worst case O(n2)O(n^2) (bad pivots), in-place.

(b) AVL tree

An AVL tree (Adelson-Velsky and Landis) 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. The balance factor of a node is

BF=h(left)−h(right)∈{−1,0,1}.BF = h(\text{left}) - h(\text{right}) \in \{-1, 0, 1\}.

After an insertion or deletion, if some node gets ∣BF∣=2|BF| = 2, the tree is rebalanced by rotations:

  • LL case (inserted in left subtree of left child): single right rotation.
  • RR case (right of right child): single left rotation.
  • LR case (right of left child): left rotation on the child, then right rotation.
  • RL case (left of right child): right rotation on the child, then left rotation.

Example: inserting 10, 20, 30 in order gives a right-skewed tree with BF(10)=−2BF(10) = -2 (RR case); a left rotation at 10 makes 20 the root with children 10 and 30.

An AVL tree with nn nodes has height O(log⁡n)O(\log n), so search, insertion and deletion all take O(log⁡n)O(\log n) time, unlike an ordinary BST which can degrade to O(n)O(n).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2079 · 10 marks

Why do we need to balance the binary search tree? Justify with an example. Create an AVL tree from the data 24, 12, 8, 15, 35, 30, 57, 40, 45, 78.

Answer

Why balancing is needed. A binary search tree (BST) gives search, insert and delete in O(h)O(h), where hh is the height. The shape of the tree depends on the order of insertion. If keys arrive in sorted order the BST degenerates into a linked list with h=nh = n, so every operation costs O(n)O(n). A balanced tree keeps h=O(log⁡n)h = O(\log n), so all operations stay O(log⁡n)O(\log n).

Example. Insert 10, 20, 30, 40, 50 into an ordinary BST. Each key becomes the right child of the previous one, giving a chain of height 5. Searching 50 needs 5 comparisons, and for n=106n = 10^6 keys it would need 10610^6. If the tree is kept balanced (an AVL tree), the same 5 keys form a tree of height 3 (root 20, children 10 and 40, and 30, 50 under 40), and for n=106n = 10^6 at most about 20 comparisons are needed.

An AVL tree is a BST in which, for every node, the balance factor BF=h(left)−h(right)∈{−1,0,1}BF = h(\text{left}) - h(\text{right}) \in \{-1, 0, 1\}. After an insertion that makes some node's BF become ±2\pm 2, the tree is repaired by rotations (LL, RR, LR, RL).

Construction of the AVL tree for 24, 12, 8, 15, 35, 30, 57, 40, 45, 78.

  1. Insert 24: root 24.
  2. Insert 12: left child of 24.
  3. Insert 8: left of 12. Node 24 has BF =+2= +2 (LL case). Right rotation at 24 gives root 12 with children 8 and 24.
  4. Insert 15: goes to the left of 24. Tree: 12 (8, 24(15, -)). Balanced.
  5. Insert 35: right of 24. Tree: 12 (8, 24(15, 35)). Balanced.
  6. Insert 30: left of 35. Node 12 now has BF =1−3=−2= 1 - 3 = -2 (RR case, since 24 is right-heavy). Left rotation at 12 gives root 24 with left subtree 12(8, 15) and right subtree 35(30, -).
  7. Insert 57: right of 35. Balanced: 35(30, 57).
  8. Insert 40: left of 57. Tree: 24 ( 12(8,15), 35(30, 57(40,-)) ). Balanced.
  9. Insert 45: right of 40. Node 57 has BF =+2= +2 and its left child 40 is right-heavy (LR case). Left rotation at 40 then right rotation at 57 makes 45 the subtree root with children 40 and 57. Now 35(30, 45(40, 57)).
  10. Insert 78: right of 57. Node 35 has BF =1−3=−2= 1 - 3 = -2 and its right child 45 is right-heavy (RR case). Left rotation at 35 makes 45 the subtree root with left child 35(30, 40) and right child 57(-, 78).

Final AVL tree

              24
            /    \
          12      45
         /  \    /   \
        8   15  35    57
               /  \     \
              30  40     78

Check: 24's left subtree has height 2 and right subtree has height 3 (BF =−1= -1); 45 has two subtrees of height 2 (BF =0= 0); every other node has ∣BF∣≤1|BF| \le 1. In-order traversal gives 8, 12, 15, 24, 30, 35, 40, 45, 57, 78, which is sorted, so the BST property holds.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2079 · 10 marks

How recursive algorithm uses stack to store intermediate results? Illustrate with an example. Convert the infix expression A+B-(CD/E+F)-GH into postfix expression using stack.

Answer

Recursion and the stack. When a function calls itself, each call needs its own parameters, local variables and return address. The system keeps these in an activation record (stack frame) pushed onto the call stack. The most recent call must finish first, which is exactly LIFO order. When the base case is reached the frames are popped one by one, and each returned value is used to complete the pending computation of the caller. So the stack stores the intermediate (pending) results.

Example: factorial.

int fact(int n) {
    if (n <= 1) return 1;        /* base case */
    return n * fact(n - 1);      /* recursive case */
}

For fact(4):

  • Calling phase (push): fact(4) waits for fact(3), which waits for fact(2), which waits for fact(1). The stack holds frames n=4, 3, 2, 1 (top is n=1).
  • fact(1) returns 1 and its frame is popped.
  • Returning phase (pop): fact(2) computes 2×1=22 \times 1 = 2, fact(3) computes 3×2=63 \times 2 = 6, fact(4) computes 4×6=244 \times 6 = 24.

Infix to postfix: A + B - (C * D / E + F) - G * H

Rules: operands go to output; an operator pops operators of higher or equal precedence (left associative) before being pushed; ( is pushed; ) pops until (.

SymbolStack (bottom to top)Output
AA
++A
B+A B
-- (pop +)A B +
(- (A B +
C- (A B + C
*- ( *A B + C
D- ( *A B + C D
/- ( / (pop *)A B + C D *
E- ( /A B + C D * E
+- ( + (pop /)A B + C D * E /
F- ( +A B + C D * E / F
)- (pop +, remove "(")A B + C D * E / F +
-- (pop -, push -)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
endpop allA B + C D * E / F + - G H * -

Postfix expression: A B + C D ∗ E / F + − G H ∗ −A\,B\,+\,C\,D\,*\,E\,/\,F\,+\,-\,G\,H\,*\,-

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2079 · 10 marks

How do you insert and delete a node at k^th position of the doubly linked list? Describe the process of implementing stack and queue using linked list.

Answer

Doubly linked list node.

struct node {
    int data;
    struct node *prev, *next;
};

Insertion at the k-th position (positions start at 1; head is the first node).

  1. Create a new node n and store the data.
  2. If k=1k = 1: n->next = head; n->prev = NULL; if head != NULL set head->prev = n; then head = n.
  3. Otherwise move a pointer p to the (k−1)(k-1)-th node. If the list is shorter, report an invalid position.
  4. Set n->next = p->next; n->prev = p;
  5. If p->next != NULL, set p->next->prev = n.
  6. Set p->next = n.
struct node *insertK(struct node *head, int x, int k) {
    struct node *n = malloc(sizeof(struct node)), *p = head;
    n->data = x;
    if (k == 1) {
        n->prev = NULL; n->next = head;
        if (head) head->prev = n;
        return n;
    }
    for (int i = 1; i < k - 1 && p; i++) p = p->next;
    if (!p) { free(n); printf("Invalid position\n"); return head; }
    n->next = p->next; n->prev = p;
    if (p->next) p->next->prev = n;
    p->next = n;
    return head;
}

Deletion of the k-th node.

  1. If the list is empty, report underflow.
  2. Move a pointer p to the kk-th node; if it does not exist, report an invalid position.
  3. If p->prev != NULL, set p->prev->next = p->next; otherwise (deleting the first node) set head = p->next.
  4. If p->next != NULL, set p->next->prev = p->prev.
  5. free(p).
struct node *deleteK(struct node *head, int k) {
    struct node *p = head;
    for (int i = 1; i < k && p; i++) p = p->next;
    if (!p) { printf("Invalid position\n"); return head; }
    if (p->prev) p->prev->next = p->next; else head = p->next;
    if (p->next) p->next->prev = p->prev;
    free(p);
    return head;
}

Both operations take O(k)O(k) time for the traversal, and the pointer changes themselves take O(1)O(1).

Stack using a linked list. A stack is LIFO, so the head of a singly linked list is used as the top. Both operations then work at the head and take O(1)O(1).

  • Push: create a node, set new->next = top, then top = new.
  • Pop: if top == NULL report underflow; else save t = top, set top = top->next, return t->data, and free(t).
  • Stack empty when top == NULL. There is no overflow except heap exhaustion, and the size is dynamic.

Queue using a linked list. A queue is FIFO, so two pointers are kept: front (delete end) and rear (insert end).

  • Enqueue: create a node with next = NULL. If the queue is empty, set front = rear = new; otherwise rear->next = new; rear = new.
  • Dequeue: if front == NULL report underflow; else t = front; front = front->next; if front becomes NULL also set rear = NULL; return the data and free(t).
  • Both operations take O(1)O(1) time and the queue never becomes "full" while memory is available.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2079 · 5 marks

Sort the numbers 82,73,12,39,26,88,2,9,60,41 using shell sort.

Answer

Shell sort sorts elements that are a gap apart using insertion sort, and reduces the gap until it is 1. For n=10n = 10 use gaps 5, 2, 1.

Initial array: 82, 73, 12, 39, 26, 88, 2, 9, 60, 41

Gap = 5. Compare the pairs (index 0, 5), (1, 6), (2, 7), (3, 8), (4, 9):

  • (82, 88): in order.
  • (73, 2): swap.
  • (12, 9): swap.
  • (39, 60): in order.
  • (26, 41): in order.

Result: 82, 2, 9, 39, 26, 88, 73, 12, 60, 41

Gap = 2. Sort the two interleaved sub-lists by insertion sort.

  • Even positions: 82, 9, 26, 73, 60 sorted gives 9, 26, 60, 73, 82.
  • Odd positions: 2, 39, 88, 12, 41 sorted gives 2, 12, 39, 41, 88.

Result: 9, 2, 26, 12, 60, 39, 73, 41, 82, 88

Gap = 1. Ordinary insertion sort on the nearly sorted array: 2 moves before 9; 12 moves before 26; 39 moves before 60; 41 moves before 60; the rest are already in place.

Sorted array: 2, 9, 12, 26, 39, 41, 60, 73, 82, 88

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2079 · 5 marks

Why do we need asymptotic notation? Describe about Big oh notation with its curve.

Answer

Need for asymptotic notation. The exact running time of an algorithm depends on the machine, compiler, language and input, so it is hard to compare algorithms by measured time. Asymptotic notation describes how the running time (or space) grows as the input size n→∞n \to \infty, ignoring constants and lower-order terms. It lets us compare algorithms independently of hardware, and predict how they behave for large inputs. For example, 3n2+5n+73n^2 + 5n + 7 is simply described as O(n2)O(n^2).

Big O notation (upper bound). f(n)=O(g(n))f(n) = O(g(n)) if there exist positive constants cc and n0n_0 such that

0≤f(n)≤c g(n)for all n≥n0.0 \le f(n) \le c\, g(n) \quad \text{for all } n \ge n_0 .

So g(n)g(n) is an asymptotic upper bound on f(n)f(n); it is used to state the worst-case growth of an algorithm.

Curve. For n<n0n < n_0, f(n)f(n) may lie above or below c g(n)c\,g(n). From n0n_0 onward, the curve of c g(n)c\,g(n) stays above the curve of f(n)f(n):

 time
  |                       c*g(n)
  |                     /
  |                   /   ..... f(n)
  |                 / ....
  |               /..
  |             /.
  |           /.
  |         /.
  |_______/_._________________________ n
                   n0

Example. f(n)=3n+2f(n) = 3n + 2. Choose c=4c = 4, then 3n+2≤4n3n + 2 \le 4n for all n≥2n \ge 2, so f(n)=O(n)f(n) = O(n) with n0=2n_0 = 2 and c=4c = 4.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2079 · 5 marks

Define queue. Explain about enqueue and dequeue operation in circular queue.

Answer

Queue. A queue is a linear data structure in which insertion takes place at one end (rear) and deletion takes place at the other end (front), following the FIFO (First In First Out) principle. The main operations are enqueue (insert), dequeue (delete), and checking empty/full.

Circular queue. In a linear array queue, once rear reaches the last index no new element can be inserted even if free space exists at the front after dequeues. In a circular queue the array is treated as a ring: the position after the last index is index 0, so freed space is reused. Indices move using modulo arithmetic: next=(i+1) mod N\text{next} = (i + 1) \bmod N.

Initially front = rear = -1.

Enqueue(x):

  1. If (rear + 1) % N == front, the queue is full: report overflow.
  2. If the queue is empty (front == -1), set front = 0.
  3. Set rear = (rear + 1) % N.
  4. Set Q[rear] = x.

Dequeue():

  1. If front == -1, the queue is empty: report underflow.
  2. Set x = Q[front].
  3. If front == rear, the queue had one element, so set front = rear = -1.
  4. Otherwise front = (front + 1) % N.
  5. Return x.
void enqueue(int x) {
    if ((rear + 1) % N == front) { printf("Overflow\n"); return; }
    if (front == -1) front = 0;
    rear = (rear + 1) % N;
    Q[rear] = x;
}
int dequeue() {
    if (front == -1) { printf("Underflow\n"); return -1; }
    int x = Q[front];
    if (front == rear) front = rear = -1;
    else front = (front + 1) % N;
    return x;
}

Both operations take O(1)O(1) time. With this convention all NN cells can be used.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2079 · 5 marks

Write a program to implement binary search.

Answer

Binary search works on a sorted array. It compares the key with the middle element and discards half of the array each time, so it runs in O(log⁡n)O(\log n).

#include <stdio.h>

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 (key < a[mid])
            high = mid - 1;          /* search left half */
        else
            low = mid + 1;           /* search right half */
    }
    return -1;                       /* not found */
}

int main() {
    int a[100], n, key, i, pos;
    printf("Enter number of elements: ");
    scanf("%d", &n);
    printf("Enter %d elements in ascending order:\n", n);
    for (i = 0; i < n; i++)
        scanf("%d", &a[i]);
    printf("Enter element to search: ");
    scanf("%d", &key);
    pos = binarySearch(a, n, key);
    if (pos == -1)
        printf("Element not found\n");
    else
        printf("Element found at position %d\n", pos + 1);
    return 0;
}

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2079 · 5 marks

Assume you have to store the data {0,1,2,4,5,7} into a hash table of size 5, with hash function, h(x)=x%5. Apply linear probing and double hashing as collision resolution techniques.

Answer

Table size m=5m = 5 (slots 0 to 4), h(x)=x mod 5h(x) = x \bmod 5. Keys: 0, 1, 2, 4, 5, 7.

Note that there are 6 keys but only 5 slots, so one key cannot be stored unless the table is enlarged.

Initial hash values: h(0)=0, h(1)=1, h(2)=2, h(4)=4, h(5)=0, h(7)=2h(0)=0,\ h(1)=1,\ h(2)=2,\ h(4)=4,\ h(5)=0,\ h(7)=2.

(a) Linear probing: h(x,i)=(h(x)+i) mod 5h(x, i) = (h(x) + i) \bmod 5.

  • 0 goes to slot 0; 1 to slot 1; 2 to slot 2; 4 to slot 4.
  • 5: h=0h = 0 is occupied, try 1 (occupied), 2 (occupied), 3 (free), so 5 goes to slot 3.
  • 7: h=2h = 2 is occupied, then 3, 4, 0, 1 are all occupied. The table is full, so 7 cannot be inserted (overflow; the table must be resized, for example to size 7 or 11 and rehashed).
Slot01234
Key01254

(b) Double hashing: h(x,i)=(h1(x)+i⋅h2(x)) mod 5h(x, i) = (h_1(x) + i \cdot h_2(x)) \bmod 5, with h1(x)=x mod 5h_1(x) = x \bmod 5 and the second hash h2(x)=3−(x mod 3)h_2(x) = 3 - (x \bmod 3) (a value from 1 to 3).

  • 0, 1, 2, 4 go to slots 0, 1, 2, 4 without collision.
  • 5: h1=0h_1 = 0, h2=3−(5 mod 3)=1h_2 = 3 - (5 \bmod 3) = 1. Probes: slot 0 (occupied), slot 1 (occupied), slot 2 (occupied), slot 3 (free). So 5 goes to slot 3.
  • 7: h1=2h_1 = 2, h2=3−(7 mod 3)=2h_2 = 3 - (7 \bmod 3) = 2. Probes: slot 2, slot 4, slot 1, slot 3, slot 0, all occupied. The table is full, so 7 cannot be placed (overflow).
Slot01234
Key01254

Both methods place 0, 1, 2, 5, 4 in the same slots here, and both fail for 7 because five keys already fill the table. Double hashing generally spreads keys better, since the probe step depends on the key and so avoids primary clustering.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2079 · 5 marks

In which case the position of pivot element in quick sort always either in the last or the first position? Create a max heap from the numbers. {10,12,53,34,23,77,59,66,5,8}

Answer

Pivot at the first or last position. In quick sort the pivot ends up at its final sorted position after partitioning. That position is always at an extreme (first or last) when the pivot is the smallest or the largest element of the sub-array every time. This happens when the pivot is chosen as the first or last element and the array is already sorted in ascending or descending order (or all keys are equal). Each partition then splits the array into sizes 00 and n−1n-1, giving the worst case T(n)=T(n−1)+O(n)=O(n2)T(n) = T(n-1) + O(n) = O(n^2).

Building a max heap from {10, 12, 53, 34, 23, 77, 59, 66, 5, 8}. Insert the numbers one by one in the given order into the array representation (children of index ii are 2i+12i+1 and 2i+22i+2), moving each new element up while it is larger than its parent.

InsertHeap after insertion
1010
1212, 10 (swap with 10)
5353, 10, 12 (swap with 12)
3453, 34, 12, 10 (34 swaps with 10)
2353, 34, 12, 10, 23 (no swap)
7777, 34, 53, 10, 23, 12 (77 swaps with 12, then with 53)
5977, 34, 59, 10, 23, 12, 53 (59 swaps with 53)
6677, 66, 59, 34, 23, 12, 53, 10 (66 swaps with 10, then with 34)
577, 66, 59, 34, 23, 12, 53, 10, 5 (no swap)
877, 66, 59, 34, 23, 12, 53, 10, 5, 8 (no swap)

Final max heap (array): 77, 66, 59, 34, 23, 12, 53, 10, 5, 8

                 77
               /    \
            66        59
           /  \      /  \
         34    23   12   53
        /  \   /
      10    5 8

Every parent is greater than or equal to its children.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2079 · 5 marks

Evaluate the postfix expression 574-*8/4+ using stack.

Answer

Postfix expression: 5 7 4 - * 8 / 4 +. Scan left to right; push operands; on an operator pop the top two values (first pop is the right operand bb, second pop is the left operand aa), compute a  op  ba \;op\; b and push the result.

SymbolActionStack (bottom to top)
5push5
7push5, 7
4push5, 7, 4
-7−4=37 - 4 = 35, 3
*5×3=155 \times 3 = 1515
8push15, 8
/15/8=1.87515 / 8 = 1.8751.875
4push1.875, 4
+1.875+4=5.8751.875 + 4 = 5.8755.875

Result = 5.875 (equivalent to the infix expression 5×(7−4)/8+45 \times (7 - 4) / 8 + 4). With integer division the result would be 5.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2079 · 5 marks

Write short noes on: a. Priority Queue b. Breadth First traversal of a graph

Answer

(a) Priority queue. A priority queue is an abstract data type in which every element has a priority, and the element with the highest priority (or lowest, in a min-priority queue) is removed first, regardless of its arrival order. Elements with equal priority are served in FIFO order.

  • Operations: insert(x, priority), deleteMax/deleteMin(), peek(), isEmpty().
  • Implementations: unsorted array/list (insert O(1)O(1), delete O(n)O(n)), sorted list (insert O(n)O(n), delete O(1)O(1)), and the binary heap (both O(log⁡n)O(\log n)), which is the most common.
  • Applications: CPU process scheduling, Dijkstra's and Prim's algorithms, Huffman coding, event-driven simulation, and operating system job queues.

(b) Breadth First Traversal (BFS) of a graph. BFS visits the start vertex, then all its neighbours, then the neighbours of those neighbours, level by level. It uses a queue and a visited array.

Algorithm:

  1. Mark the start vertex ss visited and enqueue it.
  2. While the queue is not empty: dequeue a vertex vv and print it; for each unvisited neighbour ww of vv, mark it visited and enqueue it.

Example: for the graph with edges A-B, A-C, B-D, C-D, D-E starting at A, the order is A, B, C, D, E.

Time complexity is O(V+E)O(V + E) with an adjacency list. BFS finds the shortest path (fewest edges) in an unweighted graph and is used for connected components and level-order traversal.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2080 · 10 marks

Explain queue as an ADT. Write a program to implement linear queue. Compare linear queue with circular queue.

Answer

Queue as an ADT. A queue is a linear collection of items in which insertion is done at the rear and deletion at the front (FIFO). As an abstract data type it is defined by its data and operations, independent of implementation.

  • Data: an ordered collection of elements with a front and a rear.
  • Operations:
    • create() makes an empty queue.
    • enqueue(x) adds xx at the rear (error if full).
    • dequeue() removes and returns the front element (error if empty).
    • peek() returns the front element without removing it.
    • isEmpty() and isFull() test the state.
  • Axiom: dequeue(enqueue(create(), x)) returns xx, and elements leave in the order in which they entered.

Program: linear queue using an array (C).

#include <stdio.h>
#define MAX 5

int q[MAX], front = -1, rear = -1;

void enqueue(int x) {
    if (rear == MAX - 1) { printf("Queue overflow\n"); return; }
    if (front == -1) front = 0;
    q[++rear] = x;
}

void dequeue() {
    if (front == -1 || front > rear) { printf("Queue underflow\n"); return; }
    printf("Deleted: %d\n", q[front++]);
}

void display() {
    if (front == -1 || front > rear) { printf("Queue empty\n"); return; }
    for (int i = front; i <= rear; i++) printf("%d ", q[i]);
    printf("\n");
}

int main() {
    int ch, x;
    do {
        printf("1.Enqueue 2.Dequeue 3.Display 4.Exit: ");
        scanf("%d", &ch);
        switch (ch) {
            case 1: printf("Value: "); scanf("%d", &x); enqueue(x); break;
            case 2: dequeue(); break;
            case 3: display(); break;
        }
    } while (ch != 4);
    return 0;
}

Linear queue vs circular queue.

Linear queueCircular queue
Rear moves only forward; after rear = MAX-1 no insertion is possibleRear wraps to index 0 using (rear+1) % MAX
Space freed by dequeue is never reused (false overflow)Freed space is reused, so memory is used efficiently
Full test: rear == MAX-1Full test: (rear+1) % MAX == front
Empty test: front > rear or front == -1Empty test: front == -1
Simple to implementSlightly more complex because of modulo arithmetic
Poor use of memoryBetter use of memory

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2080 · 10 marks

Define hash table and hash function. What is collision in hashing? Explain linear probing and quadratic probing with suitable example.

Answer

Hash table. A hash table is a data structure that stores key-value records in an array and uses a hash function to compute the array index directly from the key, giving average O(1)O(1) search, insert and delete.

Hash function. A function h(k)h(k) that maps a key kk to an index in 0…m−10 \ldots m-1, where mm is the table size. A good hash function is fast to compute and distributes keys uniformly. Example (division method): h(k)=k mod mh(k) = k \bmod m.

Collision. A collision occurs when two different keys hash to the same index, h(k1)=h(k2)h(k_1) = h(k_2), k1≠k2k_1 \ne k_2. It must be resolved by a collision-resolution technique, such as chaining or open addressing (linear probing, quadratic probing, double hashing).

Both of the following are open addressing methods: all keys are stored in the table itself, and on collision other slots are probed in a fixed sequence.

Linear probing. Probe sequence: (h(k)+i) mod m(h(k) + i) \bmod m for i=0,1,2,…i = 0, 1, 2, \ldots (check the next slot sequentially). It can cause primary clustering (long runs of filled slots).

Example: m=10m = 10, h(k)=k mod 10h(k) = k \bmod 10, insert 89, 18, 49, 58, 69.

  • 89 goes to slot 9; 18 goes to slot 8.
  • 49: slot 9 is occupied, next slot 0 is free, so 49 goes to slot 0.
  • 58: slots 8, 9, 0 occupied, so 58 goes to slot 1.
  • 69: slots 9, 0, 1 occupied, so 69 goes to slot 2.
Slot0123-789
Key495869empty1889

Quadratic probing. Probe sequence: (h(k)+i2) mod m(h(k) + i^2) \bmod m for i=0,1,2,…i = 0, 1, 2, \ldots (offsets 0, 1, 4, 9, ...). It avoids primary clustering but can cause milder secondary clustering (keys with the same hash follow the same probe path).

Same keys, m=10m = 10:

  • 89 goes to slot 9; 18 goes to slot 8.
  • 49: slot 9 occupied; (9+1) mod 10=0(9 + 1) \bmod 10 = 0 is free, so 49 goes to slot 0.
  • 58: slot 8 occupied; (8+1)=9(8+1) = 9 occupied; (8+4) mod 10=2(8 + 4) \bmod 10 = 2 is free, so 58 goes to slot 2.
  • 69: slot 9 occupied; (9+1) mod 10=0(9+1) \bmod 10 = 0 occupied; (9+4) mod 10=3(9 + 4) \bmod 10 = 3 is free, so 69 goes to slot 3.
Slot01234-789
Key49empty5869empty1889

Quadratic probing may fail to find an empty slot if the table is more than half full (unless mm is prime and the load factor is below 0.5).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2080 · 10 marks

Explain AVL tree with example. Also, explain balancing algorithm for this tree.

Answer

AVL tree. An AVL tree (Adelson-Velsky and Landis) 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. The balance factor is

BF(n)=h(left subtree)−h(right subtree)∈{−1,0,+1}.BF(n) = h(\text{left subtree}) - h(\text{right subtree}) \in \{-1, 0, +1\}.

Because the height is always O(log⁡n)O(\log n), search, insertion and deletion take O(log⁡n)O(\log n) time.

Example. The tree with root 20, left child 10 (children 5 and 15) and right child 30 is an AVL tree: every node has ∣BF∣≤1|BF| \le 1. If we then insert 3 (as the left child of 5), node 20 gets BF=3−1=+2BF = 3 - 1 = +2, so the tree is no longer an AVL tree and must be rebalanced (an LL case, fixed by a right rotation at 20, giving root 10 with children 5(3, -) and 20(15, 30)).

Balancing algorithm. After inserting a key as in an ordinary BST, walk back up from the new node to the root, updating heights and balance factors. At the first (lowest) node zz with ∣BF∣=2|BF| = 2, let yy be the child of zz on the taller side and apply one of four rotations:

  1. LL case (BF(z)=+2BF(z) = +2 and BF(y)≥0BF(y) \ge 0; inserted into the left subtree of the left child): a single right rotation at zz. The left child yy becomes the root of the subtree, zz becomes its right child, and yy's old right subtree becomes zz's left subtree.
  2. RR case (BF(z)=−2BF(z) = -2 and BF(y)≤0BF(y) \le 0): a single left rotation at zz. The right child yy becomes the root, zz becomes its left child, and yy's old left subtree becomes zz's right subtree.
  3. LR case (BF(z)=+2BF(z) = +2 and BF(y)<0BF(y) < 0): left rotation at yy, then right rotation at zz. The grandchild (right child of yy) becomes the subtree root.
  4. RL case (BF(z)=−2BF(z) = -2 and BF(y)>0BF(y) > 0): right rotation at yy, then left rotation at zz.

Pseudo-code:

insert(node, key):
    ordinary BST insertion
    update height(node)
    bf = height(node.left) - height(node.right)
    if bf > 1  and key < node.left.key:   return rotateRight(node)       // LL
    if bf < -1 and key > node.right.key:  return rotateLeft(node)        // RR
    if bf > 1  and key > node.left.key:   node.left = rotateLeft(node.left);  return rotateRight(node)  // LR
    if bf < -1 and key < node.right.key:  node.right = rotateRight(node.right); return rotateLeft(node)  // RL
    return node

Illustration (RR). Inserting 10, 20, 30 gives the chain 10 -> 20 -> 30, with BF(10)=−2BF(10) = -2. A left rotation at 10 makes 20 the root with children 10 and 30, restoring balance. Each rotation takes O(1)O(1), and at most one rotation (single or double) is needed per insertion, so insertion remains O(log⁡n)O(\log n). For deletion, rebalancing may be needed at several ancestors, up to the root.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2080 · 5 marks

What is asymptotic analysis? Explain theta notation with example.

Answer

Asymptotic analysis. Asymptotic analysis studies how the running time or memory use of an algorithm grows as the input size nn becomes very large. It ignores machine-dependent constants and lower-order terms, so that algorithms can be compared by their order of growth. The common notations are Big O (upper bound), Omega (lower bound) and Theta (tight bound).

Theta notation (Θ\Theta). f(n)=Θ(g(n))f(n) = \Theta(g(n)) if there exist positive constants c1c_1, c2c_2 and n0n_0 such that

c1 g(n)≤f(n)≤c2 g(n)for all n≥n0.c_1\, g(n) \le f(n) \le c_2\, g(n) \quad \text{for all } n \ge n_0 .

So g(n)g(n) bounds f(n)f(n) from both above and below: it is a tight bound, and f(n)=Θ(g(n))f(n) = \Theta(g(n)) exactly when f(n)=O(g(n))f(n) = O(g(n)) and f(n)=Ω(g(n))f(n) = \Omega(g(n)). For large nn, the curve of f(n)f(n) is sandwiched between c1g(n)c_1 g(n) and c2g(n)c_2 g(n).

Example. Show f(n)=3n2+2n+5=Θ(n2)f(n) = 3n^2 + 2n + 5 = \Theta(n^2).

  • Lower bound: 3n2+2n+5≥3n23n^2 + 2n + 5 \ge 3n^2 for all n≥1n \ge 1, so c1=3c_1 = 3.
  • Upper bound: for n≥1n \ge 1, 2n≤2n22n \le 2n^2 and 5≤5n25 \le 5n^2, so f(n)≤3n2+2n2+5n2=10n2f(n) \le 3n^2 + 2n^2 + 5n^2 = 10 n^2, giving c2=10c_2 = 10.

Hence 3n2≤f(n)≤10n23n^2 \le f(n) \le 10 n^2 for all n≥1n \ge 1, with n0=1n_0 = 1, so f(n)=Θ(n2)f(n) = \Theta(n^2).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2080 · 5 marks

Explain push and pop operations of stack. What are different applications of stack?

Answer

A stack is a linear data structure in which insertion and deletion are done only at one end, called the top (LIFO: Last In First Out).

Push (insert). Using an array S[MAX] with top = -1 initially:

  1. If top == MAX - 1, report stack overflow and stop.
  2. Increment top.
  3. Set S[top] = x.

Pop (delete).

  1. If top == -1, report stack underflow and stop.
  2. Set x = S[top].
  3. Decrement top.
  4. Return x.
void push(int x) {
    if (top == MAX - 1) printf("Overflow\n");
    else S[++top] = x;
}
int pop() {
    if (top == -1) { printf("Underflow\n"); return -1; }
    return S[top--];
}

Both operations take O(1)O(1) time.

Applications of a stack:

  • Function calls and recursion (the call stack stores return addresses and local variables).
  • Conversion of expressions: infix to postfix or prefix.
  • Evaluation of postfix and prefix expressions.
  • Balanced parentheses checking and syntax parsing in compilers.
  • Undo/redo in editors, and back/forward navigation in browsers.
  • Reversing a string or list.
  • Depth-first search of graphs, and backtracking (maze solving, N-queens).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2080 · 5 marks

Explain tail recursion with example. Compare recursion with iteration.

Answer

Tail recursion. A recursive function is tail recursive if the recursive call is the very last operation executed in the function, so nothing remains to be done after the call returns. The result of the recursive call is returned directly. Because no pending work remains, a compiler can reuse the same stack frame (tail-call optimisation) and convert the recursion into a loop, using O(1)O(1) stack space.

Example. Factorial in the ordinary (non-tail) form is return n * fact(n-1); where a multiplication still waits after the call. The tail-recursive version uses an accumulator:

int factTail(int n, int acc) {
    if (n <= 1) return acc;
    return factTail(n - 1, n * acc);   /* last action is the call */
}
/* call: factTail(4, 1) -> factTail(3,4) -> factTail(2,12) -> factTail(1,24) -> 24 */

Recursion vs iteration.

RecursionIteration
A function calls itself until a base case is reachedA loop (for/while) repeats a block until a condition fails
Uses the call stack, so extra memory, usually O(n)O(n)Constant extra memory, usually O(1)O(1)
Slower because of function-call overheadGenerally faster
Risk of stack overflow for deep recursion or a missing base caseNo such risk; a wrong condition causes an infinite loop
Code is shorter and more natural for tree, graph and divide-and-conquer problems (Tower of Hanoi, tree traversal)Code can be longer for such problems
Termination by base caseTermination by loop condition

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2080 · 5 marks

Trace selection sort algorithm with array of numbers 2, 81, 6, 45, 11, 21, 23, 41, and 11.

Answer

Selection sort: in pass ii, find the minimum of the unsorted part (positions ii to the end) and swap it with the element at position ii. The array has n=9n = 9 elements, so 8 passes are needed.

Initial: 2, 81, 6, 45, 11, 21, 23, 41, 11

PassMinimum foundArray after the pass (sorted part before the bar)
12 (already in position 1)2 | 81, 6, 45, 11, 21, 23, 41, 11
26, swap with 812, 6 | 81, 45, 11, 21, 23, 41, 11
311 (first one), swap with 812, 6, 11 | 45, 81, 21, 23, 41, 11
411 (last one), swap with 452, 6, 11, 11 | 81, 21, 23, 41, 45
521, swap with 812, 6, 11, 11, 21 | 81, 23, 41, 45
623, swap with 812, 6, 11, 11, 21, 23 | 81, 41, 45
741, swap with 812, 6, 11, 11, 21, 23, 41 | 81, 45
845, swap with 812, 6, 11, 11, 21, 23, 41, 45 | 81

Sorted array: 2, 6, 11, 11, 21, 23, 41, 45, 81

The number of comparisons is n(n−1)2=36\frac{n(n-1)}{2} = 36 and the time complexity is O(n2)O(n^2) in all cases.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2080 · 5 marks

Explain binary search with an example. What is the time complexity of binary search?

Answer

Binary search. Binary search finds a key in a sorted array. It compares the key with the middle element; if equal the search ends, if the key is smaller the search continues in the left half, otherwise in the right half. Each step halves the search range.

Algorithm: low = 0, high = n-1; while low <= high: mid = (low + high) / 2; if a[mid] == key return mid; else if key < a[mid] set high = mid - 1; else low = mid + 1. If the loop ends, the key is absent.

Example. Array: 5, 12, 18, 23, 34, 45, 56 (indices 0 to 6). Search for 45.

Steplowhighmida[mid]Decision
10632345 > 23, so low = 4
246545found at index 5

Found in 2 comparisons, while linear search would need 6.

Time complexity. Each iteration halves the range: n,n/2,n/4,…,1n, n/2, n/4, \ldots, 1. The number of iterations kk satisfies n/2k=1n / 2^k = 1, so k=log⁡2nk = \log_2 n.

  • Worst and average case: O(log⁡n)O(\log n).
  • Best case (key at the middle): O(1)O(1).
  • Space: O(1)O(1) for the iterative version.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2080 · 5 marks

Write Dijkstra’s algorithm to find shortest path between any two vertices of a graph.

Answer

Dijkstra's algorithm finds the shortest path from a source vertex to all other vertices (and hence to any destination) in a weighted graph with non-negative edge weights. It is a greedy algorithm.

Algorithm (source ss, destination tt):

  1. For every vertex vv set dist[v] = infinity, prev[v] = NULL, and mark it unvisited. Set dist[s] = 0.
  2. Repeat while there are unvisited vertices:
    1. Select the unvisited vertex uu with the smallest dist[u]; mark it visited. (If u=tu = t we may stop.)
    2. For each neighbour vv of uu that is unvisited, let w(u,v)w(u,v) be the edge weight. If dist[u] + w(u,v) < dist[v], set dist[v] = dist[u] + w(u,v) and prev[v] = u (relaxation).
  3. The shortest distance to tt is dist[t]. The path is found by following prev from tt back to ss.

Pseudo-code:

Dijkstra(G, s):
    for each vertex v: dist[v] = INF; prev[v] = NIL; visited[v] = false
    dist[s] = 0
    while some vertex is unvisited:
        u = unvisited vertex with minimum dist
        visited[u] = true
        for each neighbour v of u:
            if not visited[v] and dist[u] + w(u,v) < dist[v]:
                dist[v] = dist[u] + w(u,v)
                prev[v] = u

Complexity. With an adjacency matrix and a linear scan for the minimum: O(V2)O(V^2). With an adjacency list and a binary-heap priority queue: O((V+E)log⁡V)O((V + E)\log V).

The algorithm fails if the graph has negative edge weights (use Bellman-Ford instead).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2080 · 5 marks

Write a program to implement insertion sort.

Answer

Insertion sort builds the sorted array one element at a time. For each element (the key), it is compared with the elements before it, larger elements are shifted one place right, and the key is inserted in its correct position. Time complexity is O(n2)O(n^2) in the worst and average cases and O(n)O(n) in the best case (already sorted); it is stable and in place.

#include <stdio.h>

void insertionSort(int a[], int n) {
    for (int i = 1; i < n; i++) {
        int key = a[i];
        int j = i - 1;
        while (j >= 0 && a[j] > key) {
            a[j + 1] = a[j];     /* shift larger element right */
            j--;
        }
        a[j + 1] = key;          /* place the key */
    }
}

int main() {
    int a[100], n, i;
    printf("Enter number of elements: ");
    scanf("%d", &n);
    printf("Enter %d elements:\n", n);
    for (i = 0; i < n; i++)
        scanf("%d", &a[i]);

    insertionSort(a, n);

    printf("Sorted array: ");
    for (i = 0; i < n; i++)
        printf("%d ", a[i]);
    printf("\n");
    return 0;
}

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2080 · 5 marks

Write short notes on: a. Abstract data type b. Circular linked list

Answer

(a) Abstract data type (ADT). An ADT is a mathematical model of a data structure that specifies the data it holds and the operations that can be performed on it, without saying how they are implemented. The user sees only the interface (what is done), while the implementation (how) is hidden, which gives abstraction and encapsulation. Examples: stack (push, pop, peek, isEmpty), queue (enqueue, dequeue), list, tree. The same ADT can have different implementations; for example, a stack can use an array or a linked list. Advantages are modularity, reusability, and the ability to change the implementation without changing the user's code.

(b) Circular linked list. A circular linked list is a linked list in which the last node points back to the first node instead of NULL, so the nodes form a ring and there is no NULL pointer. It can be singly circular (each node has next) or doubly circular (next and prev).

  • A pointer to the last node (tail) gives access to both ends: tail->next is the head, so insertion at the front or end is O(1)O(1).
  • Traversal starts from any node and stops when it returns to the start node.
  • Advantages: any node can be reached from any other, and it suits round-robin scheduling, circular buffers and repeated cycling through a list.
  • Disadvantage: careless traversal can loop forever, since there is no NULL end marker.
 tail --> [C | * ] -> [A | * ] -> [B | * ] -+
              ^                              |
              +------------------------------+

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2081 · 10 marks

Define circular queue. How queue differ from stack. Write a program to implement linear queue.

Answer

Circular queue. A circular queue is a queue implemented on an array in which the last position is logically connected back to the first position, so the array behaves like a ring. After the rear reaches the last index, the next insertion goes to index 0 if that cell is free. Indices advance as (i+1) mod N(i + 1) \bmod N. This removes the problem of a linear queue where freed cells at the front cannot be reused.

Queue vs stack.

QueueStack
FIFO: First In First OutLIFO: Last In First Out
Insertion at the rear, deletion at the frontInsertion and deletion both at the top
Two pointers: front and rearOne pointer: top
Operations: enqueue, dequeueOperations: push, pop
The oldest element is removed firstThe newest element is removed first
Uses: CPU scheduling, buffering, BFSUses: recursion, expression evaluation, DFS, undo

Program for a linear queue (C).

#include <stdio.h>
#define MAX 5

int q[MAX], front = -1, rear = -1;

void enqueue(int x) {
    if (rear == MAX - 1) { printf("Queue overflow\n"); return; }
    if (front == -1) front = 0;
    q[++rear] = x;
    printf("%d inserted\n", x);
}

void dequeue() {
    if (front == -1 || front > rear) { printf("Queue underflow\n"); return; }
    printf("Deleted: %d\n", q[front++]);
}

void display() {
    if (front == -1 || front > rear) { printf("Queue is empty\n"); return; }
    printf("Queue: ");
    for (int i = front; i <= rear; i++) printf("%d ", q[i]);
    printf("\n");
}

int main() {
    int choice, x;
    do {
        printf("\n1.Enqueue  2.Dequeue  3.Display  4.Exit\nChoice: ");
        scanf("%d", &choice);
        switch (choice) {
            case 1: printf("Enter value: "); scanf("%d", &x); enqueue(x); break;
            case 2: dequeue(); break;
            case 3: display(); break;
            case 4: break;
            default: printf("Invalid choice\n");
        }
    } while (choice != 4);
    return 0;
}

Enqueue and dequeue both take O(1)O(1) time.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2081 · 10 marks

What is AVL tree? How heap differ from tree? Construct an AVL tree for data 24,12,8,15,35,30,57,40,45 and 78.

Answer

AVL tree. An AVL tree is a self-balancing binary search tree in which, for every node, the balance factor BF=h(left)−h(right)BF = h(\text{left}) - h(\text{right}) is −1-1, 00 or +1+1. When an insertion or deletion makes ∣BF∣=2|BF| = 2 at some node, rotations (LL, RR, LR, RL) restore the balance. Its height is O(log⁡n)O(\log n), so search, insert and delete take O(log⁡n)O(\log n).

Heap vs tree (binary search tree).

HeapBinary search tree
A complete binary treeNeed not be complete; any shape
Ordering: each parent is ≥\ge (max-heap) or ≤\le (min-heap) its childrenOrdering: left subtree << node << right subtree
No ordering between siblings, so in-order traversal is not sortedIn-order traversal gives sorted keys
Finds the maximum or minimum in O(1)O(1)Finds the minimum or maximum in O(h)O(h)
Search for an arbitrary key is O(n)O(n)Search is O(h)O(h), which is O(log⁡n)O(\log n) if balanced
Usually stored in an arrayUsually stored with pointers
Used for priority queues and heap sortUsed for searching and ordered data

Construction of the AVL tree for 24, 12, 8, 15, 35, 30, 57, 40, 45, 78.

  1. Insert 24, then 12 (left of 24), then 8 (left of 12). Node 24 has BF=+2BF = +2 (LL case). A right rotation at 24 gives root 12 with children 8 and 24.
  2. Insert 15 (left of 24) and 35 (right of 24). The tree is 12 (8, 24(15, 35)) and is balanced.
  3. Insert 30 (left of 35). Node 12 has BF=1−3=−2BF = 1 - 3 = -2 (RR case). A left rotation at 12 gives root 24 with left subtree 12(8, 15) and right subtree 35(30, -).
  4. Insert 57 (right of 35) and 40 (left of 57). Balanced.
  5. Insert 45 (right of 40). Node 57 has BF=+2BF = +2 and its left child 40 is right-heavy (LR case). Rotate left at 40 and then right at 57: 45 becomes the subtree root with children 40 and 57. Now 35 has children 30 and 45(40, 57).
  6. Insert 78 (right of 57). Node 35 has BF=1−3=−2BF = 1 - 3 = -2 and its right child 45 is right-heavy (RR case). A left rotation at 35 makes 45 the subtree root, with left child 35(30, 40) and right child 57(-, 78).

Final AVL tree

              24
            /    \
          12      45
         /  \    /   \
        8   15  35    57
               /  \     \
              30  40     78

All nodes satisfy ∣BF∣≤1|BF| \le 1, and the in-order traversal 8, 12, 15, 24, 30, 35, 40, 45, 57, 78 is sorted.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2081 · 5 marks

Explain big oh notation in brief. Find big oh of the following function: f(x) = 5x^4 + 9x^2 + 7x + 9.

Answer

Big O notation. Big O gives an asymptotic upper bound on the growth rate of an algorithm's running time (or space) for large input size. It is used to describe the worst-case behaviour and ignores constant factors and lower-order terms.

Formally, f(n)=O(g(n))f(n) = O(g(n)) if there exist positive constants cc and n0n_0 such that

f(n)≤c g(n)for all n≥n0.f(n) \le c\, g(n) \quad \text{for all } n \ge n_0 .

So g(n)g(n) grows at least as fast as f(n)f(n) for large nn. Common orders are O(1)<O(log⁡n)<O(n)<O(nlog⁡n)<O(n2)<O(2n)O(1) < O(\log n) < O(n) < O(n\log n) < O(n^2) < O(2^n).

Big O of f(x)=5x4+9x2+7x+9f(x) = 5x^4 + 9x^2 + 7x + 9.

For x≥1x \ge 1 we have x2≤x4x^2 \le x^4, x≤x4x \le x^4 and 1≤x41 \le x^4, so

f(x)=5x4+9x2+7x+9≤5x4+9x4+7x4+9x4=30x4.f(x) = 5x^4 + 9x^2 + 7x + 9 \le 5x^4 + 9x^4 + 7x^4 + 9x^4 = 30x^4 .

Hence f(x)≤30 x4f(x) \le 30\,x^4 for all x≥1x \ge 1, i.e. c=30c = 30 and x0=1x_0 = 1 satisfy the definition. Therefore

f(x)=O(x4).f(x) = O(x^4).

The leading term dominates; the coefficient 5 and the lower terms 9x2,7x,99x^2, 7x, 9 are ignored.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2081 · 5 marks

Convert the infix expression A+(((B-C)*(D-E)+F)/G)$(H-I) into post expression using stack.

Answer

Convert A+(((B−C)∗(D−E)+F)/G)USD(H−I)A+(((B-C)*(D-E)+F)/G)USD(H-I) to postfix using a stack.

Precedence (high to low): USDUSD (exponent, right associative) > ∗* , // > ++ , −-. Rules: operands go straight to the output; an operator pops from the stack every operator of higher precedence (or equal precedence, for left-associative operators) before being pushed; ( is pushed; ) pops until the matching (.

SymbolStack (bottom to top)Postfix output
AA
++A
(+ (A
(+ ( (A
(+ ( ( (A
B+ ( ( (A B
-+ ( ( ( -A B
C+ ( ( ( -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 -
++ ( ( +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 /
(+ $ (A B C - D E - * F + G /
H+ $ (A B C - D E - * F + G / H
-+ $ ( -A B C - D E - * F + G / H
I+ $ ( -A B C - D E - * F + G / H I
)+ $A B C - D E - * F + G / H I -
end(pop all)A B C - D E - * F + G / H I - $ +

(When + is read the first time the stack is empty, and when + inside the brackets is read it pops *, because * has higher precedence. The $ is pushed on + because it has higher precedence.)

Postfix expression:

A  B  C  −  D  E  −  ∗  F  +  G  /  H  I  −  USD  +A\; B\; C\; -\; D\; E\; -\; *\; F\; +\; G\; /\; H\; I\; -\; USD\; +

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2081 · 5 marks

Write a program to find GCD of two numbers using recursion.

Answer

GCD using recursion (Euclid's algorithm). The GCD of aa and bb satisfies

gcd⁡(a,b)={aif b=0gcd⁡(b,  a mod b)otherwise.\gcd(a,b) = \begin{cases} a & \text{if } b = 0 \\ \gcd(b,\; a \bmod b) & \text{otherwise.} \end{cases}

#include <stdio.h>

int gcd(int a, int b) {
    if (b == 0)
        return a;               /* base case */
    return gcd(b, a % b);       /* recursive case */
}

int main(void) {
    int x, y;
    printf("Enter two numbers: ");
    scanf("%d %d", &x, &y);
    printf("GCD of %d and %d is %d\n", x, y, gcd(x, y));
    return 0;
}

Trace for gcd⁡(48,18)\gcd(48, 18): gcd⁡(48,18)→gcd⁡(18,12)→gcd⁡(12,6)→gcd⁡(6,0)=6\gcd(48,18) \to \gcd(18,12) \to \gcd(12,6) \to \gcd(6,0) = 6. So the output is GCD of 48 and 18 is 6.

The recursion terminates because the second argument strictly decreases at every call and finally becomes 0. The time complexity is O(log⁡(min⁡(a,b)))O(\log(\min(a,b))).

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2081 · 5 marks

What is the application of spanning tree? Draw a MST of a graph containing any 8 vertices and 11 edges with arbitrary edge costs.

Answer

Spanning tree. A spanning tree of a connected graph GG with nn vertices is a subgraph that contains all the vertices, is connected and has no cycle, so it has exactly n−1n-1 edges. In a weighted graph, the spanning tree with the least total edge cost is the minimum spanning tree (MST).

Applications of spanning trees:

  • Designing least-cost networks: laying telephone, electrical, water, gas or computer network cables to connect all sites with minimum total length/cost.
  • Network routing and broadcasting without loops (spanning tree protocol in Ethernet switches).
  • Approximation algorithms for the travelling salesman problem and other routing problems.
  • Cluster analysis, image segmentation and circuit design (connecting pins with minimum wire).

Example graph (8 vertices, 11 edges). Vertices A to H with edge costs:

AB = 4, AC = 8, BC = 11, BD = 9, CE = 7, CF = 1, DE = 2, DG = 7, EF = 6, FH = 2, GH = 4.

Kruskal's algorithm: sort the edges by cost and add an edge if it does not form a cycle.

EdgeCostDecision
CF1accept
DE2accept
FH2accept
AB4accept
GH4accept
EF6accept (joins {D,E} with {C,F,H,G})
CE7reject (C and E already connected, cycle)
DG7reject (cycle)
AC8accept (joins {A,B} with the rest; now 7 edges)
BD, BC9, 11reject

The MST has n−1=7n-1 = 7 edges: CF, DE, FH, AB, GH, EF, AC.

Total cost=1+2+2+4+4+6+8=27.\text{Total cost} = 1+2+2+4+4+6+8 = 27.

        A --4-- B
        |
        8
        |
        C --1-- F --2-- H --4-- G
                |
                6
                |
                E --2-- D

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2081 · 5 marks

Sort the number {82, 73, 12, 39, 26, 88, 2, 9, 60, 41} using shell sort.

Answer

Shell sort sorts elements that are a gap hh apart using insertion sort, then reduces the gap until it is 1. For 10 elements take gaps 5,2,15, 2, 1.

Original: 82, 73, 12, 39, 26, 88, 2, 9, 60, 41 (positions 0 to 9)

Pass 1, gap = 5. Sublists (positions ii and i+5i+5): (82, 88), (73, 2), (12, 9), (39, 60), (26, 41). Sorting each pair gives (82, 88), (2, 73), (9, 12), (39, 60), (26, 41).

After pass 1: 82, 2, 9, 39, 26, 88, 73, 12, 60, 41

Pass 2, gap = 2. Sublist of even positions: 82, 9, 26, 73, 60, which sorts to 9, 26, 60, 73, 82. Sublist of odd positions: 2, 39, 88, 12, 41, which sorts to 2, 12, 39, 41, 88.

After pass 2: 9, 2, 26, 12, 60, 39, 73, 41, 82, 88

Pass 3, gap = 1 (ordinary insertion sort on the nearly sorted list):

  • 2 moves before 9: 2, 9, 26, 12, 60, 39, 73, 41, 82, 88
  • 12 moves before 26: 2, 9, 12, 26, 60, 39, 73, 41, 82, 88
  • 39 moves before 60: 2, 9, 12, 26, 39, 60, 73, 41, 82, 88
  • 41 moves before 60: 2, 9, 12, 26, 39, 41, 60, 73, 82, 88

Sorted list: 2, 9, 12, 26, 39, 41, 60, 73, 82, 88

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2081 · 5 marks

What is hashing? how do you apply linear probing and rehashing explain with example.

Answer

Hashing. Hashing is a technique to store and retrieve records directly using a hash function h(k)h(k) that maps a key kk to an index (address) in a hash table, giving O(1)O(1) average search, insertion and deletion. A common function is h(k)=k mod mh(k) = k \bmod m, where mm is the table size (preferably prime). When two different keys map to the same index, a collision occurs and must be resolved.

Linear probing (open addressing). If the slot h(k)h(k) is occupied, probe the next slots sequentially (wrapping round) until an empty one is found:

hi(k)=(h(k)+i) mod m,i=0,1,2,…h_i(k) = (h(k) + i) \bmod m, \quad i = 0, 1, 2, \dots

Example: m=10m = 10, h(k)=k mod 10h(k) = k \bmod 10, insert 50, 700, 76, 85, 92, 73, 101.

Keyh(k)ProbesPlaced at
5000 free0
70000 full, 1 free1
766free6
855free5
922free2
733free3
10111, 2, 3 full, 4 free4

Table: index 0 = 50, 1 = 700, 2 = 92, 3 = 73, 4 = 101, 5 = 85, 6 = 76, 7 to 9 empty.

Disadvantage: primary clustering, long runs of occupied slots form and make probing slower. Search follows the same probe sequence until the key or an empty slot is found.

Rehashing. Rehashing is used when the table becomes too full (load factor λ=n/m\lambda = n/m exceeds about 0.5 to 0.7), so that probe sequences become long or insertion fails. A new table about twice as large (next prime number) is created, and every existing key is re-inserted by applying the new hash function h(k)=k mod mnewh(k) = k \bmod m_{new}. (The term is also used for applying a second hash function when a collision occurs, as in double hashing hi(k)=(h1(k)+i h2(k)) mod mh_i(k) = (h_1(k) + i\,h_2(k)) \bmod m.)

Example: table size m=7m = 7 holding 13, 15, 6, 24 using linear probing: 13 goes to 6, 15 to 1, 6 collides at 6 and goes to 0, 24 goes to 3. Load factor =4/7>0.5= 4/7 > 0.5, so rehash into m=17m = 17 (next prime above 14):

13 mod 17 = 13, 15 mod 17 = 15, 6 mod 17 = 6, 24 mod 17 = 7.

All keys now sit at their home slots without collision. Rehashing costs O(n)O(n) but happens rarely, so insertion remains cheap on average.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2081 · 5 marks

What is the algorithm for node insertion and deletion from specified position from doubly linked list.

Answer

A doubly linked list node has a data field and two pointers, prev and next.

struct node {
    int data;
    struct node *prev, *next;
};

head points to the first node. Positions are counted from 1.

Insertion at position pos (new element x)

  1. Create a new node new; if memory is not available, report overflow.
  2. new->data = x
  3. If pos == 1 (insertion at the beginning):
    • new->prev = NULL; new->next = head
    • if head != NULL, head->prev = new
    • head = new; stop.
  4. Otherwise set temp = head and move it forward pos - 2 times (temp is now the node after which the new node goes); if temp becomes NULL, the position is invalid.
  5. new->next = temp->next
  6. new->prev = temp
  7. If temp->next != NULL, temp->next->prev = new
  8. temp->next = new
  9. Stop.
void insert_at(int x, int pos) {
    struct node *new = malloc(sizeof(struct node)), *t = head;
    new->data = x;
    if (pos == 1) {
        new->prev = NULL; new->next = head;
        if (head) head->prev = new;
        head = new; return;
    }
    for (int i = 1; i < pos - 1 && t != NULL; i++) t = t->next;
    if (t == NULL) { printf("Invalid position\n"); free(new); return; }
    new->next = t->next;
    new->prev = t;
    if (t->next) t->next->prev = new;
    t->next = new;
}

Deletion from position pos

  1. If head == NULL, report underflow and stop.
  2. Set temp = head.
  3. If pos == 1: head = temp->next; if head != NULL, head->prev = NULL; free(temp); stop.
  4. Otherwise move temp forward pos - 1 times; if temp becomes NULL, the position is invalid.
  5. temp->prev->next = temp->next
  6. If temp->next != NULL, temp->next->prev = temp->prev
  7. free(temp); stop.
void delete_at(int pos) {
    struct node *t = head;
    if (head == NULL) { printf("Underflow\n"); return; }
    for (int i = 1; i < pos && t != NULL; i++) t = t->next;
    if (t == NULL) { printf("Invalid position\n"); return; }
    if (t->prev) t->prev->next = t->next; else head = t->next;
    if (t->next) t->next->prev = t->prev;
    free(t);
}

Both operations need O(n)O(n) time to reach the position, but the actual relinking takes constant time, and no previous-node pointer has to be tracked during deletion because each node holds its own prev pointer.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2081 · 5 marks

What is linear queue? Why do we need circular queue? Explain.

Answer

Linear queue. A queue is a FIFO linear data structure: elements are inserted at the rear and deleted from the front. In an array implementation of size NN, front and rear start at −1-1 (or 0); enqueue increments rear and stores the item (overflow when rear == N-1); dequeue removes the item at front and increments front (underflow when the queue is empty).

void enqueue(int x) {
    if (rear == N - 1) { printf("Overflow\n"); return; }
    if (front == -1) front = 0;
    q[++rear] = x;
}
int dequeue(void) {
    if (front == -1 || front > rear) { printf("Underflow\n"); return -1; }
    return q[front++];
}

Why a circular queue is needed. In a linear queue, positions freed by dequeue at the front can never be reused. For example, with N=5N = 5, enqueue A, B, C, D, E (rear = 4), then dequeue twice (front = 2). The queue holds only 3 elements, but rear == N-1, so it reports overflow although two slots (0 and 1) are empty. Space is wasted, and the only way out is to shift all elements left, which costs O(n)O(n).

A circular queue treats the array as a ring: after the last index, rear (and front) wrap round to index 0 using modular arithmetic:

rear=(rear+1) mod N,front=(front+1) mod Nrear = (rear + 1) \bmod N, \qquad front = (front + 1) \bmod N

The queue is full when (rear+1) mod N=front(rear + 1) \bmod N = front and empty when front == -1 (or front == rear in the variant that keeps one slot unused).

void enqueue(int x) {
    if ((rear + 1) % N == front) { printf("Overflow\n"); return; }
    if (front == -1) front = 0;
    rear = (rear + 1) % N;
    q[rear] = x;
}
int dequeue(void) {
    if (front == -1) { printf("Underflow\n"); return -1; }
    int x = q[front];
    if (front == rear) front = rear = -1;     /* last element removed */
    else front = (front + 1) % N;
    return x;
}

In the example above, the next enqueue places the item at index 0, so all NN slots can be used. Advantages: efficient use of memory, both operations take O(1)O(1) time, and no shifting is needed. It is used in CPU scheduling, buffering (keyboard, printer spooling) and traffic systems.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

  • 2081 · 5 marks

Write short notes on:
  • Breadth First traversal of graph
  • TOH

Answer

Breadth First traversal (BFS) of a graph. BFS visits the start vertex, then all its adjacent (unvisited) vertices, then all vertices at distance 2, and so on, i.e. level by level. A queue is used to remember the vertices whose neighbours are still to be explored, and a visited array prevents revisiting.

Algorithm BFS(G, s):

  1. Mark s visited and enqueue s.
  2. While the queue is not empty:
    • dequeue a vertex v and process (print) it;
    • for every neighbour w of v that is not visited, mark w visited and enqueue w.
  3. Stop.

Example: for edges A-B, A-C, B-D, C-D, C-E starting at A: queue A; visit A, enqueue B, C; visit B, enqueue D; visit C, enqueue E; visit D; visit E. Traversal order: A B C D E.

Time complexity is O(V+E)O(V + E) with an adjacency list (O(V2)O(V^2) with a matrix). Uses: shortest path in unweighted graphs, finding connected components, level-order traversal, web crawling and peer-to-peer network broadcasting.

Tower of Hanoi (TOH). There are three pegs (source A, auxiliary B, destination C) and nn disks of different sizes stacked on A with the largest at the bottom. The task is to move all disks to C, moving one disk at a time and never placing a larger disk on a smaller one.

Recursive solution for nn disks:

  1. Move the top n−1n-1 disks from A to B (using C).
  2. Move the largest disk from A to C.
  3. Move the n−1n-1 disks from B to C (using A).
void toh(int n, char from, char to, char aux) {
    if (n == 0) return;
    toh(n - 1, from, aux, to);
    printf("Move disk %d from %c to %c\n", n, from, to);
    toh(n - 1, aux, to, from);
}

The number of moves satisfies T(n)=2T(n−1)+1T(n) = 2T(n-1) + 1, T(0)=0T(0)=0, giving

T(n)=2n−1.T(n) = 2^n - 1 .

For n=3n = 3 (7 moves): 1: A to C, 2: A to B, 1: C to B, 3: A to C, 1: B to A, 2: B to C, 1: A to C. TOH is a classic example of recursion.

Answer checked by Claude Sonnet · Oct 21, 2026

Test yourself · 2 MCQs

Loading…

Questions from TU BSc CSIT 2075 Third Semester Numerical Method (TU IOST board exam, 2075), TU BSc CSIT 2077 Third Semester Numerical Method (TU IOST board exam, 2077), TU BSc CSIT 2078 Third Semester Numerical Method (TU IOST board exam, 2078), TU BSc CSIT 2079 Third Semester Numerical Method (TU IOST board exam, 2079), TU BSc CSIT 2080 Third Semester Numerical Method (TU IOST board exam, 2080), TU BSc CSIT 2081 Third Semester Numerical Method (TU IOST board exam, 2081), TU BSc CSIT 2075 Third Semester Computer Architecture (TU IOST board exam, 2075), TU BSc CSIT 2077 Third Semester Computer Architecture (TU IOST board exam, 2077), TU BSc CSIT 2078 Third Semester Computer Architecture (TU IOST board exam, 2078), TU BSc CSIT 2079 Third Semester Computer Architecture (TU IOST board exam, 2079), TU BSc CSIT 2080 Third Semester Computer Architecture (TU IOST board exam, 2080), TU BSc CSIT 2081 Third Semester Computer Architecture (TU IOST board exam, 2081), TU BSc CSIT 2075 Third Semester Computer Graphics (TU IOST board exam, 2075), TU BSc CSIT 2077 Third Semester Computer Graphics (TU IOST board exam, 2077), TU BSc CSIT 2078 Third Semester Computer Graphics (TU IOST board exam, 2078), TU BSc CSIT 2079 Third Semester Computer Graphics (TU IOST board exam, 2079), TU BSc CSIT 2080 Third Semester Computer Graphics (TU IOST board exam, 2080), TU BSc CSIT 2081 Third Semester Computer Graphics (TU IOST board exam, 2081), TU BSc CSIT 2082 Third Semester Computer Graphics (TU IOST board exam, 2082), TU BSc CSIT 2074 Third Semester Data Structures and Algorithms (TU IOST board exam, 2074), TU BSc CSIT 2075 Third Semester Data Structures and Algorithms (TU IOST board exam, 2075), TU BSc CSIT 2077 Third Semester Data Structures and Algorithms (TU IOST board exam, 2077), TU BSc CSIT 2078 Third Semester Data Structures and Algorithms (TU IOST board exam, 2078), TU BSc CSIT 2079 Third Semester Data Structures and Algorithms (TU IOST board exam, 2079), TU BSc CSIT 2080 Third Semester Data Structures and Algorithms (TU IOST board exam, 2080), TU BSc CSIT 2081 Third Semester Data Structures and Algorithms (TU IOST board exam, 2081), TU BSc CSIT 2075 Third Semester Statistics II (TU IOST board exam, 2075), TU BSc CSIT 2077 Third Semester Statistics II (TU IOST board exam, 2077), TU BSc CSIT 2078 Third Semester Statistics II (TU IOST board exam, 2078), TU BSc CSIT 2079 Third Semester Statistics II (TU IOST board exam, 2079), TU BSc CSIT 2080 Third Semester Statistics II (TU IOST board exam, 2080), TU BSc CSIT 2081 Third Semester Statistics II (TU IOST board exam, 2081) and TU BSc CSIT 2082 Third Semester Statistics II (TU IOST board exam, 2082). Answers are written for this site; check them against your class notes.