ece250: add counting and quick sort
This commit is contained in:
parent
373d67f91e
commit
5a7fd4c8fe
@ -78,3 +78,74 @@ fn insert(A: Vec, &n: usize, key: i32) {
|
||||
A[i] = k;
|
||||
}
|
||||
```
|
||||
|
||||
## Sorting algorithms
|
||||
|
||||
### Quicksort
|
||||
|
||||
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.
|
||||
|
||||
```rust
|
||||
fn partition(A: Vec, left_bound: usize, right_bound: usize) {
|
||||
let i = left_bound;
|
||||
let j = right_bound;
|
||||
|
||||
while true {
|
||||
while A[j] <= A[right_bound] { j -= 1; }
|
||||
while A[i] >= A[left_bound] { i += 1; }
|
||||
|
||||
if i < j { A.swap(i, j); }
|
||||
else { return j } // new bound!
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
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() {
|
||||
counter[index + 1] += val; // ignore bounds for cleanliness please :)
|
||||
}
|
||||
return counter
|
||||
}
|
||||
```
|
||||
|
||||
Next, the prefix sum represents the correct position for each item.
|
||||
|
||||
```rust
|
||||
fn sort(A: Vec) {
|
||||
let counter = count(A, 100);
|
||||
let sorted = vec![0; A.len()];
|
||||
|
||||
for i in n..0 {
|
||||
sorted[counter[A[i]]] = A[i];
|
||||
counter[A[i]] -= 1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
Loading…
Reference in New Issue
Block a user