25-Comp-A4 Program Design and Data Structures · May 2013
Nivaar worked solution (AI-drafted; not reviewed by a licensed engineer)
National Exams — May 2013 — 98-Comp-A4 Program Design and Data Structures. Three-hour, closed-book exam, no calculator permitted. Format: eight questions, candidates answer any five (all questions equal weight; only the first five appearing in the answer book are marked). Pseudocode or a high-level language (C or C++) is acceptable throughout — marking emphasizes program operation, not syntactic detail. All eight questions are solved below for completeness. No marks breakdown per sub-part is given on the source paper beyond the "equal weight" instruction.
Reference texts: Cormen, Leiserson, Rivest & Stein, Introduction to Algorithms (3rd ed., MIT Press) — algorithm design, complexity analysis, sorting; Weiss, Data Structures and Algorithm Analysis in C (2nd ed., Pearson) — linked lists, stacks, pointer-based structures; Deitel & Deitel, C++ How to Program (9th ed., Pearson) — classes, templates, operator overloading; Kernighan & Ritchie, The C Programming Language (2nd ed.) — file I/O and arrays.
Question text not reproduced: the examination questions are © Engineers and Geoscientists BC. Open the official past paper (linked at the top of this page) to read the question, then follow the worked solution below.
int data; struct node *next;) and the standard include-guard macros STACK_H, matching every function signature given on the page.Approach. The stack's "top" is simply the head of a singly-linked list; pushing prepends a node (O(1), no traversal), and popping removes and returns the head node's data (O(1)).
/* stack.h */
#ifndef STACK_H
#define STACK_H
typedef struct node {
int data;
struct node *next;
} node;
void make_empty(void);
int is_empty(void);
void push(int i);
int pop(void);
#endif
/* stack.c */
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
static node *top = NULL;
void make_empty(void) {
while (!is_empty()) pop(); /* frees every remaining node */
}
int is_empty(void) {
return top == NULL;
}
void push(int i) {
node *n = (node *) malloc(sizeof(node));
if (n == NULL) {
fprintf(stderr, "push: out of memory\n");
exit(1);
}
n->data = i;
n->next = top; /* new node becomes the top */
top = n;
}
int pop(void) {
if (is_empty()) {
fprintf(stderr, "pop: stack is empty\n");
exit(1);
}
node *old_top = top;
int value = old_top->data;
top = old_top->next;
free(old_top);
return value;
}
Approach. Recursion is the natural fit: to print the list in reverse, first recurse to the end of the list, then print each node's data on the way back up the call stack — the call stack itself provides the LIFO reversal, with no explicit stack data structure needed.
void print_reverse(node *head) {
if (head == NULL) return; /* base case: past the last node */
print_reverse(head->next); /* recurse to the tail first */
printf("%d\n", head->data); /* then print on the way back */
}
For a list head → 3 → 7 → 2 → NULL, the recursion descends to NULL (printing nothing), then unwinds printing 2, then 7, then 3 — the correct reverse order.
| Operation | Time | Extra space |
|---|---|---|
| push / pop (part a) | $O(1)$ | $O(1)$ per call |
| print_reverse (part b) | $O(n)$ | $O(n)$ call-stack frames |