added comp-thinking notes

master
Stefan 7 months ago
parent d35875913a
commit 2238a8da3f

@ -0,0 +1,129 @@
# Sorting
Sorting is the process of converting a list of elemenets into ascending (or descending) order.
<br><br>
Programmers call `sort()`, but computer scientists write **sorting algorithms**.
<br><br>
Humans often sort by looking simultaneously at many elements and moving them around, but computers can only access a few elements at a single time.
### Comparison-based sorting
An algorithm must simply compare a list's elements with each other
# Bubble sort
The simplest sorting algorithm you can think of:
<br>**How it works**:
1. put the biggest value in the last spot in the vector
2. then the 2nd-highest in the out-but last spot
3. continue until all values have been placed
### Code implementation
```cpp
void bubbleSort(std::vector<int> &v) {
for (int nbrSorted = 0; nbrSorted < v.size() - 1; nbrSorted++) {
for (int current = 0; current < v.size() - nbrSorted - 1; current++) {
if (v.at(current) > v.at(current + 1))
std::swap(v.at(current), v.at(current + 1));
}
}
} // https://sortvisualizer.com/bubblesort
```
### Complexity
- **Time**: $O(n^2)$
- **Space**: $O(1)$
# Insertion sort
### Code implementation
```cpp
for (i = 1; i < numbers.size(); ++i) {
// Insert numbers.at(i) into sorted part
// stopping once numbers.at(i) in correct position
j = i;
while((j > 0) && (numbers.at(j) < numbers.at(j - 1))) {
std::swap(numbers.at(j), numbers.at(j - 1));
--j;
}
} // https://www.sortvisualizer.com/insertionsort/
```
### Complexity
- **Time**: $O(n^2)$
- **Space**: $O(1)$
# ⚠️ Stable sorting
- List elements with identical values
- A sorting algorithm is called **stable** if whenever there are two objects (R and S) with the same key, and R appears before S in the original list, the R will always appear before S in the sorted list.
# Using binary search in sorting
**Compare**:
- **Linear search**: for l element, compare it with all others in a list => $O(n)$
- **Binary search**: check whether an element is in the left or the right half of a list, divide recursively _log n_ times => $O(\log_2 n)$
# Merge sort
1. Divides a list into two halves
2. Sorts the two halves recursively
- Base case: **1** element
3. Merge the two sorted halves into a sorted list
### Complexity
- **Time**: $O(n \log_2 n)$
<br>Binary subdivision $O(\log_2 n)$ and linear comparison per phase $O(n)$
- **Space**: $O(n)$
<br>Needs second list to perform merging
# Quick sort
Quicksort repeatedly partitions a list into low and high parts (each unsorted) and then recursively sorts these partitions
- Base case: **1 or 0** elements left
### Pseudocode
```
algorithm quicksort(A, lo, hi) is
if lo >= 0 && hi >= 0 && lo < hi then
p = partition(A, lo, hi)
quicksort(A, lo, p)
quicksort(A, p + 1, hi)
```
```
algorithm partition(A, lo, hi) is
pivot = A[floor((hi + lo) / 2)]
l = lo - 1
r = hi + 1
loop forever
do l += 1 while A[l] < pivot
do r -= 1 while A[r] > pivot
if l >= r then return r
swap A[l] with A[4]
```
### Complexity
- **Time**: $O(n \log_2 n)$
- **On average** (sorting many lists of data): binary subdivision and linear comparison per phase => $O(n \log_2 n)$
- **Worse case**: always subdivise l vs n - l: $O(n^2)$
- **Space**: $O(1)$
# Sorting in practice
- Small data sets (fits in vectors in memory): call `sort`, using **quicksort**
- Large data sets (files on disk): **mergesort**
- Many more sorting algorithms exist
Loading…
Cancel
Save