19-Soft-A1 Algorithms & Data Structures · December 2016
Nivaar worked solution (AI-drafted; not reviewed by a licensed engineer)
National Exams — December 2016 — 04-Soft-A1 Algorithms & Data Structures. Three-hour, closed-book exam (Casio or Sharp approved calculator only). Format: seven questions; candidates pick five of their choice, and the first five as they appear in the answer book are marked, each worth 20 marks. All seven questions, and all sub-parts within them, are solved below for completeness. Implementations below use C-style pseudocode, as the exam note permits any of C, C++, Java, Python, or clean pseudocode.
Reference texts: Cormen, Leiserson, Rivest & Stein, Introduction to Algorithms (3rd ed., MIT Press) — asymptotic analysis, heaps, graph algorithms, divide-and-conquer, NP-completeness; Sedgewick & Wayne, Algorithms (4th ed., Addison-Wesley) — linked-list and array data structures, sorting, hashing; Weiss, Data Structures and Algorithm Analysis in C (2nd ed., Pearson) — array-based binary trees and heaps, ADT design.
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.
Given. Two already-sorted input arrays (for the merge step) and the unsorted array $[9,5,2,6,1,7,8,3]$ (for the full sort). Find. a merge procedure, a description of the recursive Merge Sort algorithm, and its trace on the 8 given values.
Merging combines two already-sorted lists into one sorted list by repeatedly comparing the two lists' current front elements and moving the smaller one (or either, on a tie) to the output, advancing only the list that element came from. Once one list is exhausted, the remainder of the other list is copied across unchanged, since everything left in it is already known to be no smaller than everything already output. A merge of two lists of total length $n$ does exactly $n-1$ comparisons in the worst case and runs in $O(n)$ time and $O(n)$ extra space.
void merge(int a[MAX], int b[MAX], int c[MAX + MAX], int na, int nb) {
int i = 0, j = 0, k = 0;
while (i < na && j < nb)
c[k++] = (a[i] <= b[j]) ? a[i++] : b[j++]; /* <= keeps the merge stable */
while (i < na) c[k++] = a[i++];
while (j < nb) c[k++] = b[j++];
}
Merge Sort is a divide-and-conquer algorithm: it splits the input array into two halves, recursively sorts each half independently (a base case of size 0 or 1 is already sorted), and then merges the two now-sorted halves back into one fully sorted array using the merge procedure above. Because the split is always into two roughly equal halves, the recursion has depth $O(\log n)$, and each of those $O(\log n)$ levels does $O(n)$ total work merging, giving $O(n\log n)$ overall.
void mergeSort(int a[], int lo, int hi) {
if (lo >= hi) return; /* 0 or 1 element: already sorted */
int mid = lo + (hi - lo) / 2;
mergeSort(a, lo, mid);
mergeSort(a, mid + 1, hi);
merge_inplace(a, lo, mid, hi); /* array-slice version of merge() */
}
Approach. Split repeatedly in half down to single elements, then merge pairs of sorted runs back together, level by level.
| Item | Result |
|---|---|
| Sorted array | $\boxed{[1,2,3,5,6,7,8,9]}$ |
| Recursion depth | $O(\log n)$ (3 levels for $n=8$) |
| Overall time complexity | $O(n\log n)$ |