Sorting Algorithms Masterclass
Sorting Algorithms Masterclass
■ MASTERCLASS SERIES ■
Sorting is the process of arranging elements of a list or array in a specific order (ascending or descending). It is one of
SORTING
the most fundamental operations in computer science — virtually every application relies on sorted data for efficient
searching, merging, and reporting.
ALGORITHMS
Database queries, file systems, UI rendering all rely on sorted structures
Many algorithms (e.g., closest pair, convex hull) need sorted input
Sorting is a standard measure of algorithm efficiency and design skill
Stable Equal elements maintain original relative order Merge Sort, Insertion Sort
Bubble Sort Selection Sort Insertion Sort Merge Sort Quick Sort
Unstable Equal elements may be reordered Quick Sort, Heap Sort
■
Out-of-place
■ ■
Requires additional memory proportional to input
■ Merge Sort
■
Comparison-based Compares elements to determine order All 5 algorithms here
Pseudocode Python Impl. C++ Impl. LeetCode Probs Complexity Analysis
Non-comparison Uses element values directly (counting, radix) Counting Sort, Radix Sort
Adaptive Faster when input is nearly sorted Insertion Sort, Tim Sort
{}
Insertion Sort O(n) O(n²) O(n²) O(1) Yes
Merge Sort O(n log n) O(n log n) O(n log n) O(n) Yes
■ Color guide: Best(green) O(n) = linear · O(n log n) = good · O(n²) = poor for large n
Space O(1) = in-place · O(log n) = recursive stack · O(n) = auxiliary array
How It Works
Bubble Sort repeatedly steps through the list, compares adjacent elements, and swaps them if they are in the wrong
order. The largest unsorted element 'bubbles up' to its correct position at the end of each pass. After n-1 passes, the
array is fully sorted.
Initial state: [ 5 3 8 4 2 ]
Pass 2: [ 3 4 2 | 5 8 ] ← 5 bubbled up
Pass 3: [ 3 2 | 4 5 8 ] ← 4 bubbled up
Pass 4: [ 2 | 3 4 5 8 ] ← 3 bubbled up
Sorted: [ 2 3 4 5 8 ] ✓ Done!
Pseudocode
Pseudocode TEXT
Python Implementation
bubble_sort.py PYTHON
1 def bubble_sort(arr):
2 """
3 Bubble Sort with early-exit optimisation.
4 Time: O(n) best, O(n^2) average/worst
5 Space: O(1) — in-place
6 """
7 n = len(arr)
8 for i in range(n - 1):
9 swapped = False
10 # Last i elements are already sorted
11 for j in range(0, n - 1 - i):
12 if arr[j] > arr[j + 1]:
13 arr[j], arr[j + 1] = arr[j + 1], arr[j]
14 swapped = True
15 # Optimisation: stop if no swaps in this pass
16 if not swapped:
17 break
18 return arr
19
20
21 # ■■ Test ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
22 if __name__ == "__main__":
23 data = [64, 34, 25, 12, 22, 11, 90]
24 print("Before:", data)
25 result = bubble_sort(data)
26 print("After: ", result)
27 # Output: After: [11, 12, 22, 25, 34, 64, 90]
C++ Implementation
bubble_sort.cpp CPP
1 #include <iostream>
2 #include <vector>
3 #include <algorithm>
4 using namespace std;
5
6 void bubbleSort(vector<int>& arr) {
7 int n = [Link]();
8 for (int i = 0; i < n - 1; i++) {
9 bool swapped = false;
10 // After each pass, largest element is at end
11 for (int j = 0; j < n - 1 - i; j++) {
12 if (arr[j] > arr[j + 1]) {
13 swap(arr[j], arr[j + 1]);
14 swapped = true;
15 }
16 }
17 // Early exit if already sorted
18 if (!swapped) break;
19 }
20 }
21
22 int main() {
23 vector<int> arr = {64, 34, 25, 12, 22, 11, 90};
24 bubbleSort(arr);
25 for (int x : arr) cout << x << " ";
26 // Output: 11 12 22 25 34 64 90
27 return 0;
28 }
Complexity Analysis
✓ Best Case O(n): Array is already sorted → 0 swaps, 1 pass with early-exit optimisation
Worst Case O(n²): Array is reverse sorted → n(n-1)/2 comparisons and swaps
The key optimisation: track swapped flag — if no swaps in a pass, list is sorted!
How It Works
Selection Sort divides the array into a sorted and unsorted region. On each pass, it SELECTS the minimum element
from the unsorted region and places it at the beginning of that region (by swapping with the first unsorted element).
Repeat until sorted.
Initial: [ 29 10 14 37 13 ]
Pseudocode
Pseudocode TEXT
Python Implementation
selection_sort.py PYTHON
1 def selection_sort(arr):
2 """
3 Selection Sort — always O(n^2), max n-1 swaps.
4 Time: O(n^2) for all cases
5 Space: O(1) — in-place
6 Stable: NO (swap can skip over equal elements)
7 """
8 n = len(arr)
9 for i in range(n - 1):
10 # Find the minimum in arr[i..n-1]
11 min_idx = i
12 for j in range(i + 1, n):
13 if arr[j] < arr[min_idx]:
14 min_idx = j
15 # Swap the found minimum with the first element
16 if min_idx != i:
17 arr[i], arr[min_idx] = arr[min_idx], arr[i]
18 return arr
19
20
21 # Stable version — shift instead of swap
22 def selection_sort_stable(arr):
23 n = len(arr)
24 for i in range(n):
25 min_idx = i
26 for j in range(i + 1, n):
27 if arr[j] < arr[min_idx]:
28 min_idx = j
29 # Shift right instead of swap to preserve stability
30 key = arr[min_idx]
31 while min_idx > i:
32 arr[min_idx] = arr[min_idx - 1]
33 min_idx -= 1
34 arr[i] = key
35 return arr
36
37
38 if __name__ == "__main__":
39 data = [29, 10, 14, 37, 13]
40 print("Sorted:", selection_sort(data))
41 # Output: Sorted: [10, 13, 14, 29, 37]
C++ Implementation
selection_sort.cpp CPP
1 #include <iostream>
2 #include <vector>
3 using namespace std;
4
5 void selectionSort(vector<int>& arr) {
6 int n = [Link]();
7 for (int i = 0; i < n - 1; i++) {
8 // Find minimum element in arr[i..n-1]
9 int min_idx = i;
10 for (int j = i + 1; j < n; j++) {
11 if (arr[j] < arr[min_idx])
12 min_idx = j;
13 }
14 // Swap if minimum is not at current position
15 if (min_idx != i)
16 swap(arr[i], arr[min_idx]);
17 }
18 }
19
20 // Finding k-th smallest — Selection Sort partial run
21 int kthSmallest(vector<int> arr, int k) {
22 int n = [Link]();
23 for (int i = 0; i < k; i++) {
24 int min_idx = i;
25 for (int j = i + 1; j < n; j++)
26 if (arr[j] < arr[min_idx]) min_idx = j;
27 swap(arr[i], arr[min_idx]);
28 }
29 return arr[k - 1]; // k-th smallest
30 }
31
32 int main() {
33 vector<int> arr = {29, 10, 14, 37, 13};
34 selectionSort(arr);
35 for (int x : arr) cout << x << " ";
36 // Output: 10 13 14 29 37
37 }
■ Key Insight: Selection Sort always does exactly n-1 swaps (or fewer) — great when write cost is high!
Best Case = Worst Case = O(n²): It always scans the full unsorted region regardless
Despite O(n²), it often outperforms Bubble Sort in practice due to fewer writes/swaps
Unstable: [2a, 2b, 1] → [1, 2b, 2a] — swapping can reorder equal elements
#414 Third Max Number Easy Find 3rd max via selection Easy
How It Works
Insertion Sort builds the sorted array one element at a time. It picks the next element from the unsorted region and
INSERTS it into its correct position in the sorted region by shifting larger elements one position to the right. Like
sorting playing cards in your hand.
Initial: [ 5 | 2 4 6 1 3 ]
Insert 3: [ 1 2 3 4 5 6 ] ✓ Sorted!
Pseudocode
Pseudocode TEXT
Python Implementation
insertion_sort.py PYTHON
1 def insertion_sort(arr):
2 """
3 Insertion Sort — excellent for small/nearly-sorted arrays.
4 Time: O(n) best, O(n^2) avg/worst
5 Space: O(1) in-place
6 Stable: YES — equal elements never swap relative order
7 Online: YES — can sort as new elements arrive
8 """
9 for i in range(1, len(arr)):
10 key = arr[i] # Current element to place
11 j = i - 1
12 # Shift elements greater than key to right
13 while j >= 0 and arr[j] > key:
14 arr[j + 1] = arr[j]
15 j -= 1
16 arr[j + 1] = key # Insert key at correct spot
17 return arr
18
19
20 # Binary Insertion Sort — O(n log n) comparisons, O(n^2) shifts
21 import bisect
22 def binary_insertion_sort(arr):
23 for i in range(1, len(arr)):
24 key = arr[i]
25 # Find position using binary search O(log n)
26 pos = bisect.bisect_left(arr, key, 0, i)
27 # Shift and insert
28 arr[pos + 1:i + 1] = arr[pos:i]
29 arr[pos] = key
30 return arr
31
32
33 if __name__ == "__main__":
34 data = [5, 2, 4, 6, 1, 3]
35 print("Sorted:", insertion_sort(data))
36 # Output: Sorted: [1, 2, 3, 4, 5, 6]
37 nearly_sorted = [1, 2, 3, 5, 4, 6] # Best case ~ O(n)
38 print("Nearly sorted:", insertion_sort(nearly_sorted))
C++ Implementation
insertion_sort.cpp CPP
1 #include <iostream>
2 #include <vector>
3 using namespace std;
4
5 void insertionSort(vector<int>& arr) {
6 int n = [Link]();
7 for (int i = 1; i < n; i++) {
8 int key = arr[i];
9 int j = i - 1;
10 // Move elements > key one position ahead
11 while (j >= 0 && arr[j] > key) {
12 arr[j + 1] = arr[j];
13 j--;
14 }
15 arr[j + 1] = key;
16 }
17 }
18
19 // Generalized template version
20 template <typename T>
21 void insertionSort(vector<T>& arr) {
22 int n = [Link]();
23 for (int i = 1; i < n; i++) {
24 T key = arr[i];
25 int j = i - 1;
26 while (j >= 0 && arr[j] > key) {
27 arr[j + 1] = arr[j]; j--;
28 }
29 arr[j + 1] = key;
30 }
31 }
32
33 int main() {
34 vector<int> arr = {5, 2, 4, 6, 1, 3};
35 insertionSort(arr);
36 for (int x : arr) cout << x << " ";
37 // Output: 1 2 3 4 5 6
38 return 0;
39 }
✓ Insertion Sort is the FASTEST algorithm for small arrays (n<20) and nearly-sorted data
Python's built-in sort (Timsort) and Java's [Link] use Insertion Sort for n<47
Online algorithm: can sort a stream of data as it arrives — no need to wait for all input
Binary Insertion reduces comparisons to O(n log n) but shifts remain O(n²)
#1365 How Many Smaller Numbers Easy Counting + insertion idea Good
How It Works
Merge Sort follows the Divide and Conquer paradigm. It recursively divides the array into two halves until each
sub-array has one element (already sorted), then MERGES them back in sorted order. The merge step is where the
real work happens — it's a linear-time operation to merge two sorted arrays.
Merge Sort — Divide & Conquer on [38, 27, 43, 3, 9, 82, 10]
Pseudocode
Pseudocode TEXT
Python Implementation
merge_sort.py PYTHON
1 def merge_sort(arr):
2 """
3 Merge Sort — guaranteed O(n log n) all cases.
4 Time: O(n log n) for all cases
5 Space: O(n) auxiliary array
6 Stable: YES — merge preserves order of equal elements
7 Best For: Linked lists, external sorting, stable sort needed
8 """
9 if len(arr) <= 1:
10 return arr
11
12 # Divide
13 mid = len(arr) // 2
14 left = merge_sort(arr[:mid])
15 right = merge_sort(arr[mid:])
16
17 # Conquer (merge)
18 return _merge(left, right)
19
20
21 def _merge(left, right):
22 """Merge two sorted arrays into one sorted array."""
23 result = []
24 i = j = 0
25 while i < len(left) and j < len(right):
26 if left[i] <= right[j]: # <= preserves stability
27 [Link](left[i])
28 i += 1
29 else:
30 [Link](right[j])
31 j += 1
32 [Link](left[i:]) # Remaining elements
33 [Link](right[j:])
34 return result
35
36
37 # In-place merge sort (less memory but complex)
38 def merge_sort_inplace(arr, left, right):
39 if left < right:
40 mid = (left + right) // 2
41 merge_sort_inplace(arr, left, mid)
42 merge_sort_inplace(arr, mid + 1, right)
43 _merge_inplace(arr, left, mid, right)
44
45 def _merge_inplace(arr, left, mid, right):
46 L = arr[left:mid + 1]
47 R = arr[mid + 1:right + 1]
48 i = j = 0
49 k = left
50 while i < len(L) and j < len(R):
51 if L[i] <= R[j]: arr[k] = L[i]; i += 1
52 else: arr[k] = R[j]; j += 1
53 k += 1
54 while i < len(L): arr[k] = L[i]; i += 1; k += 1
55 while j < len(R): arr[k] = R[j]; j += 1; k += 1
56
57 if __name__ == "__main__":
58 data = [38, 27, 43, 3, 9, 82, 10]
59 print("Sorted:", merge_sort(data))
60 # Output: Sorted: [3, 9, 10, 27, 38, 43, 82]
C++ Implementation
merge_sort.cpp CPP
1 #include <iostream>
2 #include <vector>
3 using namespace std;
4
5 void merge(vector<int>& arr, int left, int mid, int right) {
6 // Sizes of subarrays
7 int n1 = mid - left + 1;
8 int n2 = right - mid;
9 // Temp arrays
10 vector<int> L([Link]()+left, [Link]()+mid+1);
11 vector<int> R([Link]()+mid+1, [Link]()+right+1);
12 int i = 0, j = 0, k = left;
13 while (i < n1 && j < n2) {
14 if (L[i] <= R[j]) arr[k++] = L[i++];
15 else arr[k++] = R[j++];
16 }
17 while (i < n1) arr[k++] = L[i++];
18 while (j < n2) arr[k++] = R[j++];
19 }
20
21 void mergeSort(vector<int>& arr, int left, int right) {
22 if (left >= right) return; // Base case
23 int mid = left + (right - left) / 2; // Avoids overflow
24 mergeSort(arr, left, mid);
25 mergeSort(arr, mid + 1, right);
26 merge(arr, left, mid, right);
27 }
28
29 int main() {
30 vector<int> arr = {38, 27, 43, 3, 9, 82, 10};
31 mergeSort(arr, 0, [Link]() - 1);
32 for (int x : arr) cout << x << " ";
33 // Output: 3 9 10 27 38 43 82
34 return 0;
35 }
✓ Merge Sort GUARANTEES O(n log n) — no worst-case degradation like Quick Sort
Best choice for sorting Linked Lists (no random access needed, uses pointer rearrangement)
Used in External Sorting (large files that don't fit in memory — merge chunks)
Python's Timsort (built-in sort) is based on Merge Sort + Insertion Sort
Trade-off: Requires O(n) extra space — use Quick Sort if memory is tight
#327 Count of Range Sum Hard Divide & conquer merge Hard
How It Works
Quick Sort selects a PIVOT element and PARTITIONS the array so all elements less than pivot go left, all greater go
right. The pivot is then in its final sorted position. Recursively sort left and right sub-arrays. It's the most widely used
sort in practice due to excellent cache performance and O(n log n) average case.
Quick Sort — Lomuto Partition on [10, 80, 30, 90, 40, 50, 70]
Pseudocode TEXT
Python Implementation
1 import random
2
3 # 1. Lomuto Partition — pivot = last element
4 def _lomuto(arr, low, high):
5 pivot, i = arr[high], low - 1
6 for j in range(low, high):
7 if arr[j] <= pivot:
8 i += 1; arr[i], arr[j] = arr[j], arr[i]
9 arr[i+1], arr[high] = arr[high], arr[i+1]
10 return i + 1
11
12 def quick_sort(arr, low=None, high=None):
13 if low is None: low, high = 0, len(arr)-1
14 if low < high:
15 pi = _lomuto(arr, low, high)
16 quick_sort(arr, low, pi-1)
17 quick_sort(arr, pi+1, high)
18 return arr
19
20 # 2. Hoare Partition — pivot = first element, fewer swaps
21 def _hoare(arr, low, high):
22 pivot, i, j = arr[low], low-1, high+1
23 while True:
24 i += 1
25 while arr[i] < pivot: i += 1
26 j -= 1
27 while arr[j] > pivot: j -= 1
28 if i >= j: return j
29 arr[i], arr[j] = arr[j], arr[i]
30
31 def quick_sort_hoare(arr, low=None, high=None):
32 if low is None: low, high = 0, len(arr)-1
33 if low < high:
34 pi = _hoare(arr, low, high)
35 quick_sort_hoare(arr, low, pi)
36 quick_sort_hoare(arr, pi+1, high)
37 return arr
38
39 # 3. Randomized — avoids O(n^2) worst case
40 def quick_sort_random(arr, low=None, high=None):
41 if low is None: low, high = 0, len(arr)-1
42 if low < high:
43 r = [Link](low, high)
44 arr[r], arr[high] = arr[high], arr[r]
45 pi = _lomuto(arr, low, high)
46 quick_sort_random(arr, low, pi-1)
47 quick_sort_random(arr, pi+1, high)
48 return arr
49
50 # 4. 3-Way — for many duplicates (Dutch National Flag)
51 def quick_sort_3way(arr, low=None, high=None):
52 if low is None: low, high = 0, len(arr)-1
53 if low >= high: return arr
54 lt, gt, pivot, i = low, high, arr[low], low+1
55 while i <= gt:
56 if arr[i] < pivot:
57 arr[lt], arr[i] = arr[i], arr[lt]; lt+=1; i+=1
58 elif arr[i] > pivot:
59 arr[i], arr[gt] = arr[gt], arr[i]; gt-=1
60 else: i+=1
61 quick_sort_3way(arr, low, lt-1)
62 quick_sort_3way(arr, gt+1, high)
63 return arr
64
65 if __name__ == "__main__":
66 data = [10, 80, 30, 90, 40, 50, 70]
67 for fn in [quick_sort, quick_sort_hoare, quick_sort_random, quick_sort_3way]:
68 print(fn.__name__, ":", fn(data[:]))
69 # All → [10, 30, 40, 50, 70, 80, 90]
C++ Implementation
quick_sort.cpp CPP
1 #include <iostream>
2 #include <vector>
3 #include <algorithm> // for swap
4 #include <cstdlib> // for rand
5 using namespace std;
6
7 int partition(vector<int>& arr, int low, int high) {
8 // Median-of-three pivot for better performance
9 int mid = low + (high - low) / 2;
10 if (arr[mid] < arr[low]) swap(arr[low], arr[mid]);
11 if (arr[high] < arr[low]) swap(arr[low], arr[high]);
12 if (arr[mid] < arr[high]) swap(arr[mid], arr[high]);
13 int pivot = arr[high]; // Now pivot is median
14 int i = low - 1;
15 for (int j = low; j < high; j++) {
16 if (arr[j] <= pivot) {
17 i++;
18 swap(arr[i], arr[j]);
19 }
20 }
21 swap(arr[i + 1], arr[high]);
22 return i + 1;
23 }
24
25 void quickSort(vector<int>& arr, int low, int high) {
26 if (low < high) {
27 int pi = partition(arr, low, high);
28 quickSort(arr, low, pi - 1);
29 quickSort(arr, pi + 1, high);
30 }
31 }
32
33 // Iterative Quick Sort (avoids stack overflow for large n)
34 void quickSortIterative(vector<int>& arr, int low, int high) {
35 vector<int> stack(high - low + 1);
36 int top = -1;
37 stack[++top] = low;
38 stack[++top] = high;
39 while (top >= 0) {
40 high = stack[top--];
41 low = stack[top--];
42 int pi = partition(arr, low, high);
43 if (pi - 1 > low) { stack[++top] = low; stack[++top] = pi-1; }
44 if (pi + 1 < high) { stack[++top] = pi+1; stack[++top] = high; }
45 }
46 }
47
48 int main() {
49 vector<int> arr = {10, 80, 30, 90, 40, 50, 70};
50 quickSort(arr, 0, [Link]() - 1);
51 for (int x : arr) cout << x << " ";
52 // Output: 10 30 40 50 70 80 90
53 return 0;
54 }
■ Worst Case O(n²): Happens when pivot is always min/max (sorted or reverse-sorted array)
Fix 1: Randomized pivot makes O(n²) astronomically unlikely in practice
Fix 2: Median-of-three pivot selection (first, mid, last) — industry standard
3-Way partitioning (Dutch National Flag) handles duplicates in O(n) — e.g. all same elements
Quick Sort is typically 2-3x faster than Merge Sort in practice due to cache locality
Real-World Usage
Python built-in sort Timsort (Merge+Insertion) Adaptive, stable, O(n log n) guaranteed
Timsort is a hybrid algorithm combining Merge Sort and Insertion Sort. It was designed by Tim Peters in 2002 for
Python and is now used in Python, Java (for objects), Android, and many other platforms. It achieves O(n) on
nearly-sorted data.
These algorithms break the O(n log n) lower bound by not comparing elements. They exploit the structure of the data
(integer keys in a known range).
#215 Kth Largest Element Medium QuickSelect Partial sort O(n) avg
#272 Closest BST Values II Hard Merge Merge two sorted lists
1 # ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
2 # SORTING ALGORITHMS — COMPLETE CHEATSHEET
3 # ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
4
5 # BUBBLE SORT ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
6 # Adjacent swaps, largest bubbles to end each pass
7 # Best: O(n) Avg: O(n^2) Worst: O(n^2) Space: O(1) Stable: YES
8 def bubble(a):
9 for i in range(len(a)-1):
10 s=False
11 for j in range(len(a)-1-i):
12 if a[j]>a[j+1]: a[j],a[j+1]=a[j+1],a[j]; s=True
13 if not s: break
14 return a
15
16 # SELECTION SORT ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
17 # Find min, swap to front — always n-1 swaps maximum
18 # Best: O(n^2) Avg: O(n^2) Worst: O(n^2) Space: O(1) Stable: NO
19 def selection(a):
20 for i in range(len(a)-1):
21 m=i
22 for j in range(i+1,len(a)):
23 if a[j]<a[m]: m=j
24 a[i],a[m]=a[m],a[i]
25 return a
26
27 # INSERTION SORT ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
28 # Shift larger elements right, insert key at correct spot
29 # Best: O(n) Avg: O(n^2) Worst: O(n^2) Space: O(1) Stable: YES
30 def insertion(a):
31 for i in range(1,len(a)):
32 k,j=a[i],i-1
33 while j>=0 and a[j]>k: a[j+1]=a[j]; j-=1
34 a[j+1]=k
35 return a
36
37 # MERGE SORT ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
38 # Divide → conquer → merge two sorted halves
39 # Best: O(n log n) Avg: O(n log n) Worst: O(n log n) Space: O(n) Stable: YES
40 def merge_sort(a):
41 if len(a)<=1: return a
42 m=len(a)//2; L,R=merge_sort(a[:m]),merge_sort(a[m:])
43 res=[]; i=j=0
44 while i<len(L) and j<len(R):
45 if L[i]<=R[j]: [Link](L[i]); i+=1
46 else: [Link](R[j]); j+=1
47 return res+L[i:]+R[j:]
48
49 # QUICK SORT ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
50 # Partition around pivot, recurse on both sides
51 # Best: O(n log n) Avg: O(n log n) Worst: O(n^2) Space: O(log n) Stable: NO
52 def quick_sort(a,lo=0,hi=None):
53 if hi is None: hi=len(a)-1
54 if lo<hi:
55 i,j,p=lo-1,lo,a[hi]
56 while j<hi:
57 if a[j]<=p: i+=1; a[i],a[j]=a[j],a[i]
58 j+=1
59 a[i+1],a[hi]=a[hi],a[i+1]
60 quick_sort(a,lo,i); quick_sort(a,i+2,hi)
61 return a
62
63 # ■■ TEST ALL ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
64 data = [64, 34, 25, 12, 22, 11, 90]
65 assert bubble(data[:]) == [11,12,22,25,34,64,90]
66 assert selection(data[:]) == [11,12,22,25,34,64,90]
67 assert insertion(data[:]) == [11,12,22,25,34,64,90]
68 assert merge_sort(data[:])== [11,12,22,25,34,64,90]
69 assert quick_sort(data[:])== [11,12,22,25,34,64,90]
70 print("All sorting algorithms verified!")