A heap is a binary tree **stored in an array** in which all levels but the lowest are filled. It is guaranteed that the parent of index $i$ is greater than or equal to the element at index $i$.
- the parent of index $i$ is stored at $i/2$
- the left child of index $i$ is stored at $2i$
- the right child of index $i$ is stored at $2i+1$
Quicksort operates by selecting a **pivot point** that ensures that everything to the left of the pivot is less than anything to the right of the pivot, which is what partitioning does.
Sorting calls partitioning with smaller and smaller bounds until the collection is sorted.
```rust
fn sort(a: Vec, left: usize, right: usize) {
if left <right{
let pivot = partition(A, left, right);
sort(A, left, pivot);
sort(A, pivot+1, right);
}
}
```
- In the best case, if partitioning is even, the time complexity is $T(n)=T(n/2)+\Theta(n)=\Theta(n\log n)$.
- In the worst case, if one side only has one element, which occurs if the list is sorted, the time complexity is $\Theta(n^2)$.
### Counting sort
If items are or are linked to a number from $1..n$ (duplicates are allowed), counting sort counts the number of each number, then moves things to the correct position. Where $k$ is the size of the counter array, the time complexity is $O(n+k)$.
First, construct a count prefix sum array:
```rust
fn count(A: Vec, K: usize) {
let counter = vec![0; K];
for i in A {
counter[i] += 1;
}
for (index, val) in counter.iter_mut().enumerate() {