Exam Review

1 byte = 1111 1111 = 0x12 1 int32 = 0x00 0x00 0x00 0x00 = 4 byte = 0x12345678 1 char = 0x01 = 1 byte 1 short = 0x01 0x02 = 2 byte 1 long = 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 = 8 byte

Exam Review 1

Pointers

Arrays

Allocating a struct

Exam Tips:

Contracts

Exam Tips:

The integer quantity ____ strictly decrease because during an arbitary iteration of the loop, ____ gets strictly larger/smaller. Since the loop terminates if the quantity reaches 0 or less, and this quantity is strictly decreasing, the loop must terminate.

Interface

Interface vs. Implementation

Interface vs. Implementation

Contracts:

Exam Tips:

TODO: contracts for basic operations

Stack and Queue

Exam Tips:

Searching and Sorting Complexity

Best case complexity

Selection Sorting Merge Sort Quick Sort
Worst Case n^2 n log(n) n^2
Average Case n^2 n log(n) n log(n)
Best Case n^2 n log(n) n log(n)
In-Place Y N Y (can be)
Stable N Y Y

stable: whether sort among 2 dimension produce the same outcome

Searching and Sorting Complexity Chart

Searching and Sorting Complexity Chart

Searching and Sorting Complexity Chart

Searching and Sorting Complexity Chart

In Place - Stable Chart

In Place - Stable Chart

Exam Tips:

Big-O

O(1)<O(log(log(n)))<O(log(n))<O(log(n)^2)<O(n)<O(n*log(n))<O(n^2)<O(2^n)<O(n!)

Exam Tip: write O(x) in terms of the actual variable

Bit-wise

leftshift: << k = *2^k* rightshift: >> k = /2^k (exception shifting don't round down to zero, we round down to negative infinity.)

Exam Tips:

Integer

Modulo Ring

Modulo Ring

Modulo Arithmetics

Modulo Arithmetics

Modulo Arithmetics for Negative

Modulo Arithmetics for Negative

Solving represent positive and negative

Two's Complement

Two's Complement

Pointer

// de-referencing *p //@requires p!=NULL; (you can only use NULL for pointers, not other data type)

alloc(p) //@ensures \result != NULL;

ptr->field //@requires ptr!=NULL; (checked by compiler)

WARNINGS

In question 1 (Counting sort), just before the code for the function running_sums, the explanation line in the segment B[0,j). should have been in the segment B[0,j+1).

Exam Review 2

Void* Pointers

Don't Do:

Do:

Casting to void gives the tag. If the value if NULL, it has all the tags. Therefore, you can do int* i = NULL; void* q = (void*) i; string s = (string*) q;, but you cannot do string* s = (string*) i; You cannot cast one type to the other without going though void. Casting between two different types must go through void*.

Function Pointer

typedef int hash_fn(string s); hashing_fn* F = &key_hash;

ALWAYS PUT () around when accessing function pointer You have to establish the function pointer first using correct type then convert

Data Structure

Linked List

Interface:

Insert: O(1), add in front Remove: O(1), remove from end Access: O(n)

Auto Resize Array

TODO cost, amortize,

Dictionary & Hash Table

capacity: m (bucket) size: n (elements) load factor: n/m (average length) Hash Function: minimize collision

Insert: check for duplicates

Interface:

Binary Search Tree (BST) O(n) worst

Invariant:

AVL Tree

Invariant:

Insert:

Deletion: same as insertion

Heap (Priority Queue)

Interface:

Invariant:

Access:

pq_add: swap up (sift up) pq_rem: replace with the last element, swap with higher priority child (sift down)

ok_above

ok_above

is_heap_except_up

is_heap_except_up

is_heap_except_down

is_heap_except_down

grandparent_check

grandparent_check

is_heap_safe

is_heap_safe

is_heap

is_heap

Exam Review 3

Memory Structure

Memory Structure

Make sure castings are aligned: otherwise out-of-bound or undefined behavior two pointer with different type can be equal since pointers only store address, without element size.

Allocating Array on Stack

int E[8] allocates on the stack. You still need to initialize it! int F[] = {2, 4, 6, 8, 10} They still have type int*

Allocating Struct on Stack

struct point p;
p.x = 9;
p.y = 7;

& operation can get address of

You cannot do:

Strings

char* s1 = "hello"; it is an char pointer (or char array if you like)

Libraries

strlen: counts up to NUL, not included

strcpy(dst, src): copy up to NUL included

Different types of String

char *s1 = "hello" as TEXT segment

char *s2 = xcalloc(sizeof(char), strlen(char) + 1) as HEAP

char s3[] = "world"; char s4[] = {'s', '\0'}; char s5[5] as STACK

Summary of Undefined

Other undefined: (can be used to do security hacks)

Gain and Lost

Gain and Lost

Freeing Casted pointers

https://www.diderot.one/courses/42/post-office/30141 Freeing a casted non-void pointer is often undefined if they misaligned

Casting (added section) - implementation defined if not stated

Small unsigned -> larger unsigned: zero padding, value preserve Small signed -> larger signed: sign extend, value preserve Signed -> Unsigned -> Signed: preserve bit, value change when half used

Decimals

Float: 32 bits Double: 64 bits Calculation rounding error depend on compiler

Error Cause by Representation

Error Cause by Representation

Union and Enum

enum season {WINTER, SPRING, SUMMER, FALL};
emun season today = FALL;
if (today == WINTER) printf("snow!\n");
switch (today) {
  case WINTER:
    printf("snow!\n");
    break;
  default:
    printf("other\n");
}

Union Type allow using the same space in different ways:

Graphs

Edge: lines (e=[0, v(v-1)/2]) No Self-Edge: no (V, V) Neighbors: [0, min(v, e)]

Implicit graph: We don't need a graph data structure

Explicit graph: data structure in memory Cost: e \in O(v^2), but might be lower if we use e too.

Linked list of edges Hash set of edges Matrix List
graph_hasedge O(e) O(1) avg+amt O(1) O(min(v,e))
graph_addedge O(1) O(1) O(1) O(1)
graph_get_neighbors O(e) O(e) O(v) O(1) cuz grab
space O(v^2) O(v+e)\O(max(v,e))
Adj Mat
new v+e v^2
free 1 1
size v+e v^2
hasedge 1 1
addedge min(v,e) 1
get_neighbors 1 v
hasmore_neighbors 1 1
next_neighbor 1 1
free_neighbors 1 min(v,e)
DFS/BFS v+e min(v^2, ev)
DFS/BFS Tree v ?

Note: max(v, e) \leq v+e \leq 2\times max(v, e)

iterate neighbors: O(1)*O(min(v,e)) dense graph: e \in O(v^2) sparse graph: e \in O(v) \lor e \in O(vlog(v)) (we typically work with sparse graphs)

DFS / BFS

traversing

  1. if (v1 = v2) return true
  2. mark v1
  3. put v1 in bag
  4. while(non-empty bag) take an element if (elem = v2) return true else: mark, add elem's new neighbors to bag
  5. free mark array, bag, and neighbors

Spanning Tree

Cycle: a path from a vertex to itself

Simple Cycle: with at least one edge and without repeated edges

Computing a Spanning Tree

Edge-Centric algorithm (O(ev)?O(elog(v)))

Start with a spanning forest of singleton trees and add edges from the graph as long as they don't form a cycles (def.B)

Adding Edges

Adding Edges

Initialize T with isolated vertices of G (O(1)=graph_new)
For each edge (u, v) in G: (O(e))
  if connected(u, v): (O(v) where v=v_in_tree_so_far by DFS/BFS)
    discard the edge
  else:
    add it to T (O(1))
  stop once T has v-1 edges

costs O(ev)

- O(v^2) for sparse graphs

(it can create spanning forests) (Edge-Centric algorithm is greedy, DFS/BFS is not since they have worklist)

Vertex-Centric algorithm (O(e))

Start with a single vertex in the tree and add edges to vertices not in the tree (def.C)

Adding Vertex

Adding Vertex

Actual Algorithm

Actual Algorithm
(Complexity: O(e) as DFS/BFS)

Minimum Spanning Tree

Minimum spanning tree: one with the least total weight of its edges.

Kruskal's Algorithm (O(ev)->O(elog(e)))

We sort first

We sort first

Union Find: A way to check connectivity by grouping O(ev)

Height Tracking: Trying to build balanced tree by tracking height (O(elog(e)))

Height Tracking Array

Height Tracking Array

Complexity

Complexity

Path Compression (O(eAck^{-1}(v)) amortized)

Path Compression: Ackermann Function

Path Compression: Ackermann Function

Prim's Algorithm (O(e log e))

Using priority queue

Using priority queue

Amortized Flipping bits

Math

Token

TODO: casting print automatic TODO: https://www.rapidtables.com/convert/number/decimal-to-hex.html TODO: drawing pad

Tips:

Table of Content