25-Comp-A4 Program Design and Data Structures · December 2016
Nivaar worked solution (AI-drafted; not reviewed by a licensed engineer)
Paper format. 98-Comp-A4 Program Design and Data Structures, December 2016 — 3 hours, closed book, no calculator permitted. Nine questions of equal weight (20 marks each: 1, 2 and 9 split as (a) 10 + (b) 10); candidates answer any six, so a complete paper is 120 marks. Pseudocode or any high-level language is accepted, and the examiner's note states explicitly that marking emphasises the operation of the program, not syntactic details. All nine questions are answered below, because the whole set is the more useful revision resource. Answers are given in C or C++ as the question dictates; each is compilable as written (or corrected where the printed paper itself has a slip), but a clear, correctly reasoned pseudocode answer would earn the same marks.
Reference texts for this subject.
The Computer Engineering citation list is built around architecture and networking texts (Patterson & Hennessy, Tanenbaum, Mano); this subject is programming and data structures, so the works above are cited instead.
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.
Check: the printed declaration has two defects of the anonymous-typedef struct kind: (1) typedef struct {...node *next;...} node; uses the
name node for the pointer field before the
typedef that introduces it has finished — this does not
compile in C, and is corrected below to a tagged
struct node {...struct node *next;...};. (2) the paper closes
the header guard as #end if (two words), which no preprocessor
accepts; it is corrected to #endif below. (The guard's opening
#ifndef QUEUE_H / #define QUEUE_H is printed
correctly on the paper — only the closing directive is split.) Also,
a single top pointer (naming that suggests a stack, not a queue)
would force an $O(n)$ traversal to find the rear on every enqueue; the
implementation below adds a second rear pointer so enqueue and
dequeue are both $O(1)$, which is what "insertion at the rear, deletion at
the head" implies a queue module should provide.
Given. A queue ADT with four operations
(make_empty, is_empty, enqueue,
dequeue) to be backed by a singly linked list.
Find. A working implementation of all four operations, each $O(1)$.
Approach. Keep two pointers, front (head, the
next element to dequeue) and rear (tail, where the next
enqueued element is linked in); enqueue appends after rear,
dequeue removes and frees front.
queue.h.
#ifndef QUEUE_H
#define QUEUE_H
struct node {
int data;
struct node *next;
};
void make_empty(void);
int is_empty(void);
void enqueue(int i);
int dequeue(void);
#endifqueue.c.
#include <stdio.h>
#include <stdlib.h>
#include "queue.h"
static struct node *front = NULL; /* head: next to dequeue */
static struct node *rear = NULL; /* tail: last enqueued */
void make_empty(void) {
while (!is_empty()) dequeue();
}
int is_empty(void) {
return front == NULL;
}
void enqueue(int i) {
struct node *n = (struct node *)malloc(sizeof(struct node));
n->data = i;
n->next = NULL;
if (rear == NULL) { /* queue was empty */
front = rear = n;
} else {
rear->next = n;
rear = n;
}
}
int dequeue(void) {
struct node *old;
int value;
if (is_empty()) {
fprintf(stderr, "Error: dequeue from empty queue\n");
exit(1);
}
value = front->data;
old = front;
front = front->next;
if (front == NULL) rear = NULL; /* queue just became empty */
free(old);
return value;
}dequeue()
returns 1 and advances front to the node holding 2; the second
returns 2 and advances front to the node holding 3 —
elements come out in the same order they went in, which is exactly the FIFO
behaviour a queue (as opposed to a stack) requires.
$$\boxed{\text{dequeue order for enqueue}(1,2,3) = 1,\,2,\,(3\text{ remains})}$$| Operation sequence | Output / state |
|---|---|
| enqueue(1); enqueue(2); enqueue(3) | front→1→2→3←rear |
| dequeue() | returns 1 |
| dequeue() | returns 2 |
| Time complexity, both operations | $O(1)$ (front & rear pointers) |