UTSC // Computer Science

CSCA48_

SYSTEM ONLINE
Introduction to Computer Science II
C Programming · Data Structures · Algorithms
🔑 AI features need your Anthropic API key — get one free at console.anthropic.com
Stored locally in your browser only — never sent anywhere except Anthropic's API directly from your browser.

Study Topics

Select a topic to view notes, code examples, and memory diagrams

Ch.1 — C Language Foundations
C Basics & Compilation
Program structure, data types, type casting, printf/scanf, control flow, arrays, strings, gcc compilation, errors vs warnings.
Ch.2 — Memory Model
The C Memory Model
Variables as lockers, pass-by-value, local scope, function memory lifecycle, arrays in memory, strings and '\0', the 5-step problem solving process.
Ch.2 — Pointers
Pointers & Memory
Addresses, & and * operators, pointer arithmetic, double pointers (**), passing pointers to functions, arrays and pointers, pointer+offset notation.
Ch.2 — Dynamic Memory
malloc / free & Dynamic Allocation
calloc vs malloc, heap vs stack, NULL checks, memory leaks, double free, dangling pointers, free() rules, valgrind usage.
Ch.3 — Compound Data Types
CDTs, Structs & ADTs
typedef struct, . vs -> operators, passing CDTs, ADT vs data structure, List ADT, Queue ADT, scanf vs fgets, testing methodology.
Ch.3 — Data Structure
Linked Lists
Node struct, insert at head/tail/middle, traversal pattern, search, delete (3 cases), free_list, why **head is needed, queue implementation.
Ch.4 — Algorithm Analysis
Big-O Complexity
Big-O definition, drop constants, dominant term, linear vs binary search, bubble sort derivation O(n²), mergesort O(n log n), complexity comparison table.
Ch.4 — Data Structure
Binary Search Trees
BST property, insert (recursive), search, delete (leaf/one child/two children + successor), all 3 traversals, height, degenerate tree worst case.
Ch.5 — Recursion
Recursion
Base cases, recursive cases, call stack, tail recursion, recursive list/BST functions. Every practice coding problem uses recursion.
Ch.5 — Algorithms
Sorting Algorithms
Bubble sort O(n²), merge sort O(n log n) with full implementation, quicksort average O(n log n) / worst O(n²), complexity comparison.
Ch.5 — Data Structure
Graphs
Directed vs undirected, adjacency list vs matrix, terminology (degree, path, cycle, connected), complexity of all operations.
Ch.5 — Graph Algorithm
DFS & Graph Search
Depth-First Search, visited[] array, recursive DFS implementation, BFS and queue, path-finding applications.
Ch.6 — Software Design
Software Design & Modularity
8 design properties, modules (.h/.c files), APIs, information hiding, encapsulation in C, software licenses (MIT/GPL), debugging process.

Practice Quiz

108 questions across all chapters — pick how many you want, filter by topic, or stress-test in exam mode

Mode:
Category:
Questions:

Quick Reference

Everything you need on one page — pointer syntax, graph ops, complexity, sorting, DFS

Pointer Syntax
declare pointerint *p;
get addressp = &x;
dereference*p → value at p
double pointerint **pp;
deref double ptr**pp → value
NULL pointerp = NULL;
check nullif (p == NULL)
ptr arithmeticp++ → next element
struct fieldnode->data
struct (non-ptr)node.data
malloc / free
alloc intmalloc(sizeof(int))
alloc array[n]malloc(n*sizeof(T))
alloc + zerocalloc(n,sizeof(T))
alloc structmalloc(sizeof(Node))
always checkif (ptr==NULL) return
free memoryfree(ptr);
after freeptr = NULL; // ALWAYS
memory leaklost ptr to heap mem
double freeUB — heap corruption
stack memauto-freed on return
Linked List Patterns
insert headNode **head O(1)
insert tailtraverse first O(n)
delete nodeprev->next = cur->next
thenfree(cur); cur=NULL;
traversewhile(cur!=NULL)
free listuse post-order logic
self-ref structstruct Node *next;
why **headC pass-by-value!
BST Properties
left subtreeALL values < root
right subtreeALL values > root
in-orderL → root → R (sorted!)
pre-orderroot → L → R (copy)
post-orderL → R → root (free)
search avgO(log n) balanced
search worstO(n) degenerate
BST is a graphparent→child edges
Graph Terminology
G = (V, E)nodes + edges
undirectededges go both ways
directededges have direction
neighbouradjacent node
degree# of neighbours
in-degree# edges pointing IN
out-degree# edges going OUT
pathsequence of nodes
cycle (undir)path ≥3, same start/end
N, M|V| nodes, |E| edges
Adjacency List vs Matrix
adj list spaceO(N+M) ✓ sparse
adj matrix spaceO(N²) ✗ sparse
edge query listO(N) traverse
edge query matrixO(1) direct access
add edge listO(1) insert at head
add edge matrixO(1) set A[i][j]=1
remove edge listO(N) traverse
remove edge matrixO(1) set A[i][j]=0
add node listO(N) resize array
add node matrixO(N²) resize matrix
remove node listO(M) scan all lists
remove node matrixO(N) zero row+col
undirected matrixsymmetric: A[i][j]=A[j][i]
Recursion Rules
base casetrivial — return directly
recursive casecall self on smaller input
no base casestack overflow / crash
depth# calls until base case
stack framememory per function call
tail recursiverecursive call is LAST op
tail rec benefitO(1) stack space
regular rec cost~70% slower than loops
when to recurseproblem has recursive struct
Sorting Complexity
bubble sortO(n²) always
selection sortO(n²) always
insertion bestO(n) nearly sorted
insertion worstO(n²) reverse sorted
mergesortO(n log n) ALWAYS
mergesort splithalve array → log n levels
quicksort avgO(n log n)
quicksort worstO(n²) bad pivot always
merge step costO(n) per level
best general sortO(n log n) lower bound
DFS Algorithm
base case 1current == destination
base case 2no unvisited neighbours
step 1visited[current] = 1
step 2for each unvisited neighbour
step 3DFS(neighbour, dest, ...)
step 4prepend current to subpath
visited[]size N, init all zeros
DFS exploresdeep before wide
BFS exploreswide (uses queue)
Common Bugs & Fixes
Forget free() → memory leak
free() twice → heap corruption
Use after free → undefined behavior
NULL deref → segfault
No NULL check after malloc → crash
Off-by-one → i<=n instead of i<n
Missing base case → stack overflow
No visited[] in DFS → infinite loop
Pass *head not **head → head not updated
Uninit variable → junk value used
Complexity & BSTs — Ch.4
Big-Of(N) ≤ c·g(N), large N
drop constantsO(5N) = O(N)
fastest term winsO(N²+N) = O(N²)
linear searchO(N) avg & worst
binary searchO(log N) — sorted only
bubble sortO(N²) always
mergesortO(N log N) guaranteed
BST propertyleft < root ≤ right
BST search avgO(log N)
BST search worstO(N) sorted insert
BST insert avgO(log N)
BST delete avgO(log N)
delete case aleaf: just remove
delete case b1 child: link parent→child
delete case c2 children: promote successor
successormin of right subtree
in-orderL→Root→R = sorted
pre-orderRoot→L→R = copy tree
post-orderL→R→Root = free tree
balanced height⌊log₂(N)⌋
degenerate heightN-1 (sorted insert)
CDTs & Linked Lists — Ch.3
. operatorfield of variable
-> operatorfield via pointer
CDT passedby VALUE (copies all)
ADTwhat, not how
data structurespecific implementation
empty listhead == NULL
calloc(n,sz)alloc + zero n items
check callocif (ptr == NULL)
insert headO(1)
insert tailO(n) traverse first
searchO(n) traverse
delete headhead = head->next
free listsave next before free
queue enqueueadd at TAIL
queue dequeueremove from HEAD
scanf stringsuse fgets() instead
primary keyuniquely IDs each item
Memory Model — Ch.2
uninit valuecontains JUNK
scoperegion where var is valid
local varonly visible in its function
pass by valuefunction gets a COPY
fn memoryreserved on call, freed on return
return 0success; >0 = error code
(float)xexplicit type cast
int/intinteger division!
float→inttruncates (no rounding)
array[N]N contiguous boxes
valid index[0, N-1] only
OOB accessundefined behavior / crash
stringchar array + '\0' at end
'\0'end-of-string delimiter
strcpy/strcatauto-manage '\0'
&xaddress of x
*(p)contents of locker p
*(p+n)contents n lockers after p
arr passedby reference (ptr to [0])
segfaultaccessed unowned memory
Software Design — Ch.6
.h filedeclarations = public API
.c fileimplementation
static fnhidden to other files
info hidingonly expose what users need
dependency#include creates dependency
modularityone component, one task
gcc -ccompile → .o object file
linkercombines .o → executable
MIT/BSDpermissive license
GPLcopyleft — result stays open
debug step 1reproduce the bug
debug step 2know correct output first
debug step 3trace with printf()
8 propertiesmodularity→security
C Basics & Compilation — Ch.1
compilegcc file.c
named outputgcc file.c -o name
run (Linux)./a.out
entry pointint main()
statement endsemicolon ;
import lib#include<stdio.h>
comment// or /* ... */
intinteger number
doublereal number
charsingle character
voidno type / returns nothing
%d %f %c %sprintf specifiers
\n \tnewline, tab
&& || !logical AND OR NOT
% operatormodulo (remainder)
breakexit loop immediately
errorcompile fails — must fix
warningcompiles but likely a bug
Memory Debugging Tools
valgrindLinux/Mac
Dr. MemoryLinux/Mac/Windows
run valgrindvalgrind ./a.out
run DrMem./drmemory -- ./a.out
catchesleaks, double-free, uninit
log output./a.out > log.txt
time programtime ./a.out

Key Code Patterns

// ─── Linked List Node ─────────────────────────────────────
typedef struct Node { int data; struct Node *next; } Node;

// Insert at head — needs ** to update caller's pointer
void insert_head(Node **head, int val) {
    Node *n = (Node*)malloc(sizeof(Node));
    if (!n) return;
    n->data = val;  n->next = *head;  *head = n;
}

// ─── BST Insert (recursive) ────────────────────────────────
BST_Node *insert(BST_Node *root, int val) {
    if (!root) { /* malloc new node, set key, left=right=NULL */ return n; }
    if (val < root->key) root->left  = insert(root->left,  val);
    else               root->right = insert(root->right, val);
    return root;
}

// ─── DFS Path Finding ──────────────────────────────────────
int DFS(int cur, int dest, int adj[][N], int visited[]) {
    visited[cur] = 1;
    if (cur == dest) return 1;  // base case 1
    for (int j = 0; j < N; j++) {
        if (adj[cur][j] && !visited[j])
            if (DFS(j, dest, adj, visited)) return 1;
    }
    return 0;  // base case 2: no path found
}

// ─── Tail Recursive Sum ────────────────────────────────────
int sum_TR(int *arr, int n, int part) {
    if (n == 0) return part + arr[0];       // base case
    return sum_TR(arr, n-1, part + arr[n]); // tail call
}

Coding Practice

Write C functions from scratch — AI will check your logic, catch bugs, and explain mistakes

// Your implementation:

Optimize

Identify the Big-O of slow code — then rewrite it to be efficient. AI grades both steps.

STEP 1 OF 2 — Identify the Big-O
// Slow function:

          

Past Midterm — Winter 2026

Actual midterm questions. Multiple choice auto-graded. Long answer checked by AI.

These questions are from the Winter 2026 midterm — for personal review only. If you're a current CSCA48 student preparing for an upcoming exam, stop here. This page is intended for students who have already written this midterm and want to review their mistakes.
// Your answer:

Course Textbook

Official lecture notes by Professor F.P. Estrada — the ground truth for this course

📖 Copyright Notice — Please Read
These notes were written by Professor F.P. Estrada (University of Toronto). A significant amount of work went into preparing them. They are freely available for teaching and learning but are distributed under a CC BY-NC-ND license — you may not redistribute, modify, or use them commercially, and you must give credit. Do not claim this work as your own.

About This Site

Why this exists and who made it

// the story

43/100 on the midterm.

That's what I got on the CSCA48 Winter 2026 midterm. Not great. I sat down afterwards and realized the issue wasn't effort — it was the way I'd been studying. Reading notes passively, not actually testing myself on code, not drilling the exact kind of questions the exam asks.

So I built this. A site that actually forces you to engage — write code in boxes, get AI feedback on it, take timed quizzes, trace through the real midterm questions. Everything I wish had existed before I walked into that exam room.

If you're in CSCA48 and you're staring down an upcoming exam, I hope this helps you more than passive re-reading ever would.

// what's inside
📚13 topic pages covering every chapter, with code examples and memory diagrams
🧠108 quiz questions — code-reading, exam-style, with shuffle and spaced repetition
💻22 AI-graded coding problems across linked lists, BSTs, and recursion
8 optimization challenges — identify Big-O, then rewrite efficiently
📝Winter 2026 midterm — 25 MC + 2 long answer questions, AI-graded
🔑Your Anthropic API key powers the AI grading — stored locally, never uploaded
// contact
name Kevin Dong
program Computer Science (Co-op) — UTSC
built with HTML/CSS/JS + Anthropic API

Found a bug? A wrong answer? A topic that needs more depth? Email me. This site is a work in progress and I'll keep improving it as the course goes on.

// disclaimer

The textbook content linked in the Textbook tab belongs entirely to Professor F.P. Estrada and is distributed under a CC BY-NC-ND license. This site links to those PDFs but does not reproduce their content.

The past midterm questions are included for personal study purposes only, based on my own exam paper. If you are an instructor who would like this content removed, please email me and I will do so promptly.

AI feedback is generated by Claude (Anthropic) using your own API key. It is a study aid, not a guaranteed grade predictor. Always verify understanding against the official course materials.