Week 1: Algorithm Analysis

Algorithm Analysis:

Terminology:

Big-O Notation (Time Complexity):

Time-complexity for different operations on common data structures:


Examples: O(1)

void swap(int a[], int i, int j) {
		int tmp = a[i];  // O(1)
		a[i] = a[j];     // O(1)
		a[j] = tmp;      // O(1)
}                    // Total: O(1)

O(n)

for (int i = 0; i < n; i++) {
		// Some O(1) statements
}   // Total: O(n)

O(n²)

for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
				// Some O(1) statements
		}
}   // Total: O(n²), basically just counting how many times the innermost
    //        statements get executed, relative to n

O(logn)

for (int i = 0; i < n; i *= 2) {
		// Some O(1) statements
}   // Total: O(log₂n)
// Eg. for n = 100, the loop will execute log₂(100) times, 
//     which is 6 or 7 times

Week 2: ADTs

Abstract Data Types:


Set ADT example: A typical abstract set data structure may support the declare the following functions in its header file:

Set newSet();
void freeSet(Set s);
void displaySet(Set s);
void setInsert(Set s, int data);
void setRemove(Set s, int target);
bool setIsMember(Set s, int target);
Set setUnion(Set s, Set t);
Set setIntersection(Set s, Set t);
int setCardinality(Set s);

Time-complexities for a set implementation using various underlying data structures:

As the person implementing an abstract data type for other users, after you decide what functions you want to supply, you have to go through each possible implementation and compare the set of time-complexities for each implementation. You choose the appropriate implementation based on which functions are most important to the specifications.


Week 3: Trees I — Binary Search Tree Basics