Volume III · complete note coverage · page by page

CMS 702 · Everything Left in the Lecture Notes

The gap-closer. Volumes I and II cover the syllabus and drill it; this volume walks the lecturer's 16 handwritten pages in order and picks up every definition, worked example and class assignment the first two did not reproduce · including the two the notes themselves left unresolved.
Prepared by Mbosinwa Awunor · www.mbosinwa.dev
Exam: Monday 03 Aug 2026 Time: 11:00 – 14:00 Venue: the exam hall Lecturer: the lecturer Units: 3

1Coverage map · every page of the notes, and where it is answered

Read this table once. If a row says Vol III, the material is in this document and you have not seen it in the other two.

Notes §PageTopicCovered inWhat is here in Volume III
11–2Algorithms · the ten typesVol IIIAll ten types defined, not just named · §2
22–3Asymptotic analysis · notations · upper & average boundsVol I §3Bound wording restated in §3
33The five complexity classesVol I §3-
44Sorting and searchingVol I §4-
55–6Hashing · components · worked example · collision · load factorVol I §5The page-5 assignment answered · §4
66Dynamic programmingVol I §4-
76–7Data structures · types · operations · arrays · linked listsVol I §1, §8-
88StacksVol I §8-
98QueuesVol I §8-
108–11Trees · terminology · node · height, depth, degreeVol I §6-
1111–12Types of trees · the perfect-tree formulasVol I §6The complete-binary-tree example from p.12 · §7
1212Binary search trees · properties · worked buildVol I §7-
1313In-order successor · Examples 1 and 2 · the assignmentVol IIIBoth examples worked · §5
1413–14In-order predecessorVol I §7-
1514BST traversal · the nine-letter class exampleVol IIIThe tree reconstructed and verified · §6
1615–16Construction from traversals · pre + in · pre + postVol IIIThe pre-order + post-order method and worked example · §7

Verdict on coverage

With this volume, every section, worked example and assignment in the 16 handwritten pages is accounted for, plus the four outline topics that never reached the notes at all (graphs, run-time storage management, numerical algorithms, string processing) which sit in Volume I §9 and §10. Nothing in the course material is now unrepresented.

2The ten types of algorithm · defined, not just listed

Volume I lists these for recall. The notes define six of them, and a question worded "list and explain any five types of algorithm" needs the explanations. One sentence each is enough.

#TypeDefinition to writeExample
1Brute forceTries all possible solutions to a specific problem until the correct one is found.Linear search; trying every password combination
2RecursiveA method that breaks a problem into smaller sub-problems and repeatedly breaks the problem down until it is able to solve it.Factorial, tree traversal, Towers of Hanoi
3EncryptionUtilises cryptographic techniques to transform data into a secure form, ensuring confidentiality and privacy in digital communication.AES, RSA
4BacktrackingUses trial-and-error techniques to explore potential solutions, abandoning a path as soon as it cannot lead to a valid solution.N-queens, sudoku solving, maze routing
5SearchDesigned to find a specific target within a dataset, enabling effective retrieval of information.Sequential search, binary search
6SortAims at arranging the elements of a list in a specific order · ascending, descending or lexicographic.Merge, quick, heap sort
7Divide and conquerDivides the problem into independent sub-problems, solves each one, and combines their solutions into the answer.Merge sort, quick sort, binary search
8GreedyMakes the choice that looks best at each step, never reconsidering, in the hope that the local optima give the global optimum.Coin change, Dijkstra, Huffman coding
9Dynamic programmingSolves a complex problem by breaking it into smaller sub-problems, solving each once and storing the result for reuse.Fibonacci, knapsack, longest common subsequence
10RandomizedUses a random choice at some point in its logic, so its behaviour or running time depends partly on chance.Randomized quick sort (random pivot)
The contrast most likely to earn a mark: divide and conquer splits a problem into independent sub-problems and combines their answers; dynamic programming applies where the sub-problems overlap, and it stores each answer so it is computed only once. Greedy differs from both · it never revisits a decision, which makes it fast but not always optimal.

3Upper and average complexity bound · the notes' own wording

Upper complexity bound

Provides a guarantee of the algorithm's performance in the worst-case scenario. It ensures the algorithm will not perform unexpectedly poorly under any circumstances. This is why Big O · the upper bound · is the notation used by default when an algorithm is analysed.

Average complexity

Considers the expected performance of an algorithm, given that all possible inputs of a certain size assume a certain distribution of input. It is more representative of everyday behaviour than the worst case, but it says nothing about the guarantee.

If a question asks you to "distinguish between the upper bound and the average complexity bound", the answer is exactly this pair: one is a guarantee under the worst input, the other is an expectation over a distribution of inputs. Add that the worst case is stated with O and the exact average behaviour with Θ.

4Page-5 assignment · the array as a map

As set in class: "Consider an array as a map where the key is the index and the value is the value at that index. Find the value at A[i], where A is the location and i is the integer."

Answer. An array is the simplest possible hash-style map: the key is the index i, the value is the element stored there, and the "hash function" is the identity function · the key is the slot number, so no transformation and no collision is possible.

The value at A[i] is found by address arithmetic, not by searching:

address of A[i] = base address of A + ( i × size of one element )

Because the machine computes that address in a fixed number of steps regardless of how large the array is, the lookup is O(1) · constant time. This is precisely the property hashing tries to buy for arbitrary keys such as strings: the hash function converts a non-numeric key into an index so that it too can be reached in one step.

A  =  Int Array(10)     base address = 1000
      element size = 4 bytes

 key (index):  0    1    2    3    4  …
 value:      [35] [33] [42] [10] [14] …
 address:    1000 1004 1008 1012 1016

A[3]  →  1000 + (3 × 4)  =  1012  →  value 10
The sentence that finishes the answer: an array is a map whose keys are restricted to consecutive integers; a hash table generalises it by allowing any key · a string or an arbitrary integer · which a hash function maps down onto those same array indices.

5In-order successor · the two class examples

Volume I gives the method; these are the exact two examples from page 13, which are small enough to be reproduced verbatim in an answer.

Example 1

root = [2, 1, 3],  K = 2

      2
     / \
    1   3

In-order = 1, 2, 3. The node after 2 is 3.

∴ successor of K = 3
Structural reading: K has a right sub-tree, so the successor is the smallest node in that right sub-tree.

Example 2

root = [3, 2, 1],  K = 3

      3
     /
    2
   /
  1

In-order = 1, 2, 3. Nothing follows 3 · it is the largest value in the tree.

∴ successor of K = −1
The convention in the notes: −1 is returned when no in-order successor exists.

The page-13 assignment

root = [20, 8, 22, 4, 12,
        N, N, N, N, 10, 14]
K = 8

          20
         /  \
        8    22
       / \
      4   12
         /  \
       10    14

In-order = 4, 8, 10, 12, 14, 20, 22.

∴ answer = 10 · worked in class.

How to read the level-order array notation

A list like [20, 8, 22, 4, 12, N, N, N, N, 10, 14] is a level-order listing: read the tree row by row, left to right, writing N for an absent child. Level 0 is 20; level 1 is 8, 22; level 2 is 4, 12 then N, N for 22's two missing children; level 3 gives 4's two missing children N, N and then 12's children 10, 14. Rebuild the picture before answering anything · never try to reason from the list itself.

6Page-14 traversal example · the tree recovered

The notes record three traversal sequences from the board but flag the tree diagram as too faint to read. The tree is fully recoverable from any two of those sequences, and it is worth having, because these letter sequences are exactly the kind of thing that reappears on a paper.

What the notes recorded

In-order    = B, D, A, G, E, C, H, F, I
Pre-order   = A, B, D, C, E, G, F, H, I
Post-order  = D, B, G, E, H, I, F, C, A

Reconstruction from pre-order + in-order

  1. First of the pre-order is the root → A. In the in-order, B D lies to its left and G E C H F I to its right.
  2. Left sub-tree: pre B D, in B D → root B; D is after B in the in-order, so D is B's right child.
  3. Right sub-tree: pre C E G F H I, in G E C H F I → root C; G E left, H F I right.
  4. Under C, left: pre E G, in G E → root E with G as its left child. Right: pre F H I, in H F I → root F with H left and I right.

The tree

              A
            /   \
          B       C
           \     /  \
            D   E     F
               /     / \
              G     H   I
Verification · all three sequences must match, and they do:
In-order (L-Root-R)B, D, A, G, E, C, H, F, I
Pre-order (Root-L-R)A, B, D, C, E, G, F, H, I
Post-order (L-R-Root)D, B, G, E, H, I, F, C, A

Note that this tree is not a binary search tree · its in-order traversal is not alphabetical. It is an ordinary binary tree, which is why the traversals must be read off the structure rather than guessed from the ordering.

7Construction from pre-order + post-order · the page-16 method

Volume I covers pre + in and post + in. The notes also work a third combination, pre-order + post-order, which behaves differently and has a caveat worth a mark.

The method

  1. The first element of the pre-order and the last element of the post-order are the same node · that is the root.
  2. Take the second element of the pre-order. That node is the root of the left sub-tree.
  3. Find that node in the post-order. Everything up to and including it forms the left sub-tree; everything after it, excluding the overall root, forms the right sub-tree.
  4. Split the pre-order the same way by size, and recurse on each side.

Worked example from the notes

Pre-order  = F, B, A, D, C, E, G, I, H   [Root,L,R]
Post-order = A, C, E, D, B, H, I, G, F   [L,R,Root]
  1. Root = first of pre = last of post = F.
  2. Second of pre = B → root of the left sub-tree. In the post-order, everything up to and including B is A, C, E, D, B → the left sub-tree; the remainder H, I, G → the right sub-tree.
  3. Left: pre B A D C E, post A C E D B → root B; its left child is A (next in pre, and A ends the left block in post), its right child is D, whose children are C and E.
  4. Right: pre G I H, post H I G → root G; next in pre is I, whose child is H.
            F
          /   \
         B     G
        / \      \
       A   D      I
          / \    /
         C   E  H
Verification: pre-order of the drawn tree = F, B, A, D, C, E, G, I, H ✓ · post-order = A, C, E, D, B, H, I, G, F ✓ · and its in-order comes out as A, B, C, D, E, F, G, H, I · alphabetical, so this one is a valid BST.
The caveat worth a mark. Pre-order + post-order does not always give a unique tree. When a node has only one child, the pair cannot tell you whether that child is the left or the right one · here, G has the single child I, and the reconstruction assumes it is the right child. The pair is unique only for a full binary tree (every node with 0 or 2 children). In-order paired with either of the other two is always unique, which is why in-order is the sequence you actually need.

The three combinations side by side

GivenWhere the root isHow to splitUnique?
Pre-order + in-orderFirst of the pre-orderFind the root in the in-order; left of it is the left sub-tree, right of it the rightAlways unique
Post-order + in-orderLast of the post-orderIdentical split on the in-orderAlways unique
Pre-order + post-orderFirst of the pre = last of the postSecond of the pre is the left sub-tree's root; locate it in the post-order and cut thereOnly for a full binary tree

8The tree-type diagrams from pages 11–12

Full binary tree

        1
       / \
      2   3
     / \
    4   5

Every node has 0 or 2 children. Node 3 is a leaf (0 children); nodes 1 and 2 have two each. No node has exactly one child.

Perfect binary tree

        1
       / \
      2   3
     / \ / \
    4  5 6  7

Every internal node has exactly 2 children and all leaves are on the same level. Here h = 2, so leaves l = 2² = 4 and nodes n = 2³ − 1 = 7

Complete binary tree P.12

        1
       / \
      2   3
     / \  /
    4  5 6

Every level filled except possibly the last, whose leaves lean left · node 3 has a left child but no right sibling for it. This is the exact diagram from the notes.

The distinction in one line each

Full · no node has exactly one child. Perfect · full and every leaf on the same level. Complete · every level filled except the last, which fills from the left. Every perfect tree is both full and complete; the converse fails in both directions · the complete tree above is not full (node 3 has one child), and a full tree can be lopsided and so not complete.

9One-page note map · the whole course in a grid

TopicThe single line you must be able to writeThe number to quote
AlgorithmStep-by-step procedure / set of instructions to solve a specific problem10 types
Asymptotic analysisRunning time as a mathematical function f(n); describes limiting behaviour3 cases, 3 notations
NotationsO upper/worst · Θ tight/both · Ω lower/best, all for n ≥ n₀-
Complexity classesConstant, logarithmic, linear, quadratic, exponentialO(1) < O(log n) < O(n) < O(n²) < O(2ⁿ)
SortingArranging list elements in a specific order5 named: merge, quick, bucket, heap, counting
SearchingFinding a target within a datasetSequential O(n) · binary O(log n), sorted only
HashingLookup · mapping arbitrary data to a tabular index via a hash function3 components · 4 properties · 2 collision fixes · O(1)
Load factorItems in the table ÷ size of the table7/10 = 0.7
Dynamic programmingBreaking a complex problem into smaller sub-problems and reusing their resultsFibonacci O(2ⁿ) → O(n)
Data structureOrganization, management and storage format enabling efficient access and modification3 categories · 6 operations
ArraysFixed-size cannot be altered, indexes numbered; dynamic can be resizedA[i] found in O(1) by address arithmetic
Linked listsNodes holding data plus a pointer to the next node3 types: singly, doubly, circular
StackADT implementing LIFO, open at one end, PUSH and POP1 pointer (top)
QueueADT implementing FIFO, open at both ends, Enqueue() and Dequeue()2 pointers (front, rear)
TreeHierarchical non-linear structure of nodes connected by edges3 properties · leaf height 0
Height / depthHeight counts up from the deepest leaf; depth counts down from the rootPerfect tree: l = 2ʰ, n = 2^(h+1) − 1
BSTLeft node less than parent, right node greater than parent4 properties · in-order is sorted
TraversalsIn L-Root-R · Pre Root-L-R · Post L-R-RootMissing successor −1 · missing predecessor null
ReconstructionPre gives the root at the front, post at the back; in-order tells you where to splitPre + post unique only for a full tree
GraphG = (V, E) · vertices joined by edgesMatrix O(V²) · list O(V + E) · BFS/DFS O(V + E)