How it works
Selects both the minimum and maximum in each pass, placing them at the beginning and end respectively. Approximately 2x fewer passes than standard selection sort.
Implementation
function doubleSelectionSort(arr, stats) { const n = arr.length; const sorted = new Set(); let left = 0, right = n - 1; while (left < right) { let minIdx = left, maxIdx = left; for (let j = left; j <= right; j++) { stats.comparisons += 2; compare(j, minIdx, { sorted }); if (arr[j] < arr[minIdx]) minIdx = j; if (arr[j] > arr[maxIdx]) maxIdx = j; } if (minIdx !== left) { [arr[left], arr[minIdx]] = [arr[minIdx], arr[left]]; if (maxIdx === left) maxIdx = minIdx; swap(left, minIdx, { sorted }); } markSorted(left); if (maxIdx !== right) { [arr[right], arr[maxIdx]] = [arr[maxIdx], arr[right]]; swap(right, maxIdx, { sorted }); } markSorted(right); left++; right--; checkpoint(left, Math.ceil(n / 2)); } if (left === right) markSorted(left); }
from types import SimpleNamespace def doubleSelectionSort(arr, stats): sorted = set() left = 0 right = (n - 1) while (left < right): minIdx = left maxIdx = left for j in range(left, (right + 1)): compare(j, minIdx, SimpleNamespace(sorted=sorted)) if (arr[j] < arr[minIdx]): minIdx = j if (arr[j] > arr[maxIdx]): maxIdx = j if (minIdx != left): arr[left], arr[minIdx] = arr[minIdx], arr[left] if (maxIdx == left): maxIdx = minIdx swap(left, minIdx, SimpleNamespace(sorted=sorted)) markSorted(left) if (maxIdx != right): arr[right], arr[maxIdx] = arr[maxIdx], arr[right] swap(right, maxIdx, SimpleNamespace(sorted=sorted)) markSorted(right) left += 1 right -= 1 checkpoint(left, -(-(n // 2) // 1)) if (left == right): markSorted(left)
#include <vector> #include <algorithm> #include <cmath> void sort(std::vector<int>& arr, int n, int& comparisons, int& swaps) { int sorted = 0; int left = 0; int right = (n - 1); while((left < right)) { int minIdx = left; int maxIdx = left; for(int j=left; j<(right + 1); j++) { comparisons += 2; compare(j, minIdx, {sorted: sorted}); if((arr[j] < arr[minIdx])) { minIdx = j; } if((arr[j] > arr[maxIdx])) { maxIdx = j; } } if((minIdx != left)) { std::swap(arr[left], arr[minIdx]); if((maxIdx == left)) { maxIdx = minIdx; } swap(left, minIdx, {sorted: sorted}); } markSorted(left); if((maxIdx != right)) { std::swap(arr[right], arr[maxIdx]); swap(right, maxIdx, {sorted: sorted}); } markSorted(right); left++; right--; checkpoint(left, (int)std::ceil((n / 2))); } if((left == right)) { markSorted(left); } }
public void Sort(int[] arr, int n, dynamic stats) { int sorted = 0; int left = 0; int right = (n - 1); while((left < right)) { int minIdx = left; int maxIdx = left; for(int j=left; j<(right + 1); j++) { compare(j, minIdx, {sorted: sorted}); if((arr[j] < arr[minIdx])) { minIdx = j; } if((arr[j] > arr[maxIdx])) { maxIdx = j; } } if((minIdx != left)) { { int _t = arr[left]; arr[left] = arr[minIdx]; arr[minIdx] = _t; } if((maxIdx == left)) { maxIdx = minIdx; } swap(left, minIdx, {sorted: sorted}); } markSorted(left); if((maxIdx != right)) { { int _t = arr[right]; arr[right] = arr[maxIdx]; arr[maxIdx] = _t; } swap(right, maxIdx, {sorted: sorted}); } markSorted(right); left++; right--; checkpoint(left, (int)Math.Ceiling((n / 2))); } if((left == right)) { markSorted(left); } }
#include <stdio.h> #include <math.h> void sort(int arr[], int n, int* comparisons, int* swaps) { int sorted = 0; int left = 0; int right = (n - 1); while((left < right)) { int minIdx = left; int maxIdx = left; for(int j=left; j<(right + 1); j++) { compare(j, minIdx, {sorted: sorted}); if((arr[j] < arr[minIdx])) { minIdx = j; } if((arr[j] > arr[maxIdx])) { maxIdx = j; } } if((minIdx != left)) { { int _t = arr[left]; arr[left] = arr[minIdx]; arr[minIdx] = _t; } if((maxIdx == left)) { maxIdx = minIdx; } swap(left, minIdx, {sorted: sorted}); } markSorted(left); if((maxIdx != right)) { { int _t = arr[right]; arr[right] = arr[maxIdx]; arr[maxIdx] = _t; } swap(right, maxIdx, {sorted: sorted}); } markSorted(right); left++; right--; checkpoint(left, (int)ceil((n / 2))); } if((left == right)) { markSorted(left); } }