Algorithm Analysis, AVL Trees & B-Trees – Comprehensive Notes
Introduction to Algorithm Analysis
- Algorithm = finite set of unambiguous instructions that always terminates & is executable by hand.
- INPUT ➜ zero or more externally supplied values.
- OUTPUT ➜ at least one value produced.
- DEFINITENESS ➜ every step is clear & unambiguous.
- FINITENESS ➜ terminates after a finite number of steps for every instance.
- EFFECTIVENESS ➜ each step is simple enough to be carried out with pencil-and-paper.
Why analyse algorithms?
- Predict behaviour without coding / machine-specific tests.
- Provides simple, machine-independent efficiency measures.
- Exact prediction impossible ⇒ analysis is an approximation.
- Enables comparison & selection of best algorithm for a task.
Types of analysis
- Best case
- Lowest run-time; lower bound on complexity.
- Ex: linear search finds key at first position.
- Worst case
- Highest run-time; upper bound.
- Ex: linear search misses key in entire array.
- Average case
- \text{Avg} = \dfrac{\sum\text{time over all inputs}}{\text{#inputs}}
Space and Time Complexity Analysis
Space complexity
- Total memory required = fixed part + variable part.
- Fixed part: code, constants, simple variables, fixed-size aggregates.
- Variable part: input-dependent structures, referenced data, recursion stack.
- Formal model: S(P)=c+SP(instance characteristics)
- Example
double sum(double a[], int n){
double s=0.0;
for(int i=1;i<=n;i++) s+=a[i];
return s;
}
- Needs space for array a (≥n words), variables n,i,s (3 words).
- Ssum(n)≥n+3 words.
Time complexity (run time)
- T(P)=compile time+tP(instance) (compile time ignored once program is reused).
- Step counting rules (primitive assignment = 1, comments = 0, loop control ≈ 1 per iteration, etc.).
Counting method 1 – instrument code
s = 0.0; // count+=1
for(i=1;i<=n;i++){ // count +=1 each test (n+1 times)
s = s + a[i]; // count+=1 executed n times
}
return s; // count+=1
- Total steps after termination =2n+3.
Counting method 2 – table
| Statement | Steps/exec | Frequency | Contribution |
|---|
| s=0 | 1 | 1 | 1 |
| for-loop test | 1 | n+1 | n+1 |
| s=s+a[i] | 1 | n | n |
| return | 1 | 1 | 1 |
| Total =2n+3. | | | |
Asymptotic Notations
Big-O O() – upper bound
- f(n)=O(g(n))⟺∃c>0,n<em>0:f(n)≤cg(n)∀n≥n</em>0
- Example: 3n+2=O(n) with c=4,n0=2.
Omega Ω() – lower bound
- f(n)=Ω(g(n))⟺∃c>0,n<em>0:f(n)≥cg(n)∀n≥n</em>0
- Example: 3n+2=Ω(n) with c=3,n0=1.
Theta Θ() – tight bound
- f(n)=Θ(g(n))⟺∃c<em>1,c</em>2>0,n<em>0:c</em>1g(n)≤f(n)≤c<em>2g(n)∀n≥n</em>0
- Example: 3n+2=Θ(n) with c<em>1=3,c</em>2=4,n0=2.
Little-o o() – non-tight upper bound
- f(n)=o(g(n))⟺limn→∞g(n)f(n)=0.
- For any c>0,∃n<em>0:0≤f(n)<cg(n) beyond n</em>0.
- Example: 7n+8∈o(n2) because ratio →0 as n→∞.
AVL Trees
Definition & balance factor
- Height-balanced BST (invented 1962 by Adelson-Velsky & Landis).
- For every node: BF=h<em>left−h</em>right∈−1,0,1 (alternate sign convention allowed).
- Every AVL is a BST; the converse is false.
Rotations (re-balancing primitives)
- Single Left (LL) – right rotation about pivot; fixes left-left heavy.
- Single Right (RR) – left rotation; fixes right-right heavy.
- Left-Right (LR) – RR on left child then LL on pivot.
- Right-Left (RL) – LL on right child then RR on pivot.
Operations
Creation
- Start with root=null.
- Insert nodes via BST rule; after each insertion update heights & BF; rotate if needed.
Insertion algorithm ((O(\log n)))
- Insert new key as leaf using BST search.
- Walk back up, update heights, compute BF.
- If a node violates BF, perform appropriate rotation (LL, RR, LR, RL) centred at first unbalanced ancestor.
Example: inserting 1→8
- Sequence of states shows LL, LR rotations; final tree perfectly balanced with height 3.
Deletion algorithm
- Delete like BST, then backtrack updating heights & BF.
- If imbalance appears, use L or R family of rotations determined by location of deletion relative to critical node.
- R0: child BF 0.
- R1: child BF +1.
- R−1: child BF −1 (equivalent to LR case).
- Examples: deleting 30 (R0), 55 (R1), 60 (R−1) illustrated.
Applications
- Situations with few updates but many searches.
- In-memory sets/dictionaries, symbol tables, gaming storyline data, any search-intensive app.
- Databases for small main-memory indices where order of input may be nearly sorted.
B-Trees
Definition & properties (order m)
- Generalised m-way search tree optimised for disk/block access.
- Max keys/node: m−1; max children: m.
- Except root & leaves, every node has ≥⌈m/2⌉ children.
- Root has at least 2 children unless it is a leaf.
- All leaves appear on same level (tree is perfectly height-balanced).
Why B-tree?
- Stores many keys per node ⇒ reduces height ⇒ minimises expensive disk I/O.
Operations
Creation
- Fix order m.
- Start with empty root.
Insertion (at leaf)
- Search down to proper leaf.
- If leaf has <m−1 keys: insert in sorted order.
- Else (overflow):
- Insert key then split at median.
- Median key moves up; split may propagate recursively. If root overflows, new root is created (height +1).
Example: order 3, insert 1-10
- Shows successive splits at 3, 6; root promotions (2 then 4) etc.; final height 3 tree.
Deletion
- Always affect a leaf first (internal key replaced by in-order predecessor/successor from leaf).
- After deletion, if a node still has ≥⌈m/2⌉ keys: done.
- Otherwise (underflow):
- Borrow from left/right sibling with >min keys via rotation through parent separator.
- Else merge with sibling + separator, reducing parent’s keys. If parent underflows, repeat upward; if root ends with 0 keys, height decreases.
Example (order 5, delete 5,12,32,53)
- Delete 5 → simple shift.
- Delete 12 → borrow from left sibling via separator 11.
- Delete 32 → borrow from right sibling via separator 51.
- Delete 53 (internal) → replace by successor 61, then handle leaf underflow by borrowing/merge resulting in balanced tree.
Complexity
- Search, insertion, deletion: O(logmN) disk accesses (height dependent on block capacity m).
Applications of B-Trees
- Database indexes (clustered & secondary) – e.g., MySQL InnoDB, PostgreSQL.
- File systems (NTFS, HFS+, ext4 extents) for directory entries & block maps.
- OS virtual-memory page tables & swap management.
- Router forwarding tables, DNS servers’ zone storage.
- Compiler symbol tables & other on-disk associative structures.
Connections & Real-World Relevance
- AVL (main-memory, pointer-rich) vs. B-Tree (disk/block-oriented). Choice depends on access cost model.
- Asymptotic analysis guides which structure suits workload (search heavy vs. update heavy, memory vs. I/O bound).
- Ethical/Practical: efficient data structures reduce energy and resource usage of large-scale systems.