From 5a7fd4c8fee396c37e574ef10cc4a39a2f2c24b6 Mon Sep 17 00:00:00 2001 From: eggy Date: Fri, 3 Nov 2023 12:40:16 -0400 Subject: [PATCH] ece250: add counting and quick sort --- docs/2a/ece250.md | 71 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/docs/2a/ece250.md b/docs/2a/ece250.md index 739245e..cdc0b5a 100644 --- a/docs/2a/ece250.md +++ b/docs/2a/ece250.md @@ -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; + } +} +```