Array Usage:
Dictionary:
key
value(call it entry if it contains a key)
Self-Resizing Array Complexity | unsorted | sorted by key | sorted by data |
---|---|---|---|
look up | O(n) | O(log n) | O(n) |
insert | O(1) amortized | O(n) | O(1) |
(Operations are fast when we know where to loop)
For a dictionary of capacity k, we mod our key by k first. If keys conflict, we can look up the value if the right key is in value.
this array is called table (hash table)
length is capacity of the table
we connect array end to start
linear probing: use next free index quadratic probing: try index +1, +4, and +9... (collisions are unavoidable)
when num_entries > table_capacity: pigeonhole principle ensure that there will be collisions
when num_entries > 1: birthday paradox will likely to get collisions
We store a linked list (chain) in each index
Worst case: look up O(n)
find bucket O(1)
go through n nodes in the chain
Best case layout
n/m is load factor(average number of elements stored in a chain) of the table
loop up worst case O(n/m), also average-case complexity
in order to reach about constant complexity O(c), re resize table when it reaches threshold c (n/m < c), we double the size of the array. Worst case becomes O(1) amortized
Amortized Cost for Add and Resizing
To get the best possible layout
keys = entries
lookup = return true or false
Client Interface // typedef ____ elem; input by the client, however, the definition need to be compiled before the library
can at most contain one type of stack
client need to split into 2 files
every C0 program is C1 program
add generic pointers, and function pointers
we can mix program with cc0 compiler
but c1 language should only be in file with .c1 extension
new pointer type: void*
this is not a pointer to void, void is not a type
the value of this type is a generic pointer
we can cast all pointers into void*
no void x = *q1;
- void is not a type
no void* x = alloc(void);
- void not a type
void[] B = alloc_array(void, n); is fine
check safety of casting (untagging pointer failed)
in contracts: \hastag(tp, ptr) -> \hastag(int*, pointer)
NULL
NULL is a valid value of void*
NULL \hastag(*, NULL) is always true
//@assert \hastag(void*,pv); will always be false
Tags: C1 check safety by maintaining tags
tags can change when change assignment
Casting diagram
Table of Content