How it works
Minimizes branches.
Implementation
function weakHeapSort(arr, stats) { const n = arr.length; if (n < 2) return; const reverse = new Uint8Array(n); const metrics = stats.educational.metrics; let finalized = 0; const recordMetric = (name, delta = 1) => { metrics[name] = (metrics[name] || 0) + delta; }; metrics.reverseBits = n; function swap(i, j) { if (i === j) return; swap(i, j); const value = arr[i]; arr[i] = arr[j]; arr[j] = value; recordMetric('pairSwaps'); } function markIndex(index) { markSorted(index); finalized++; if (finalized > n) finalized = n; checkpoint(finalized, n); } function distinguishedAncestor(index) { let ancestor = index; while ((ancestor & 1) === reverse[ancestor >> 1]) { ancestor >>= 1; recordMetric('ancestorWalkSteps'); } return ancestor >> 1; } function join(root, child) { compare(root, child); recordMetric('joinCalls'); if (arr[root] < arr[child]) { reverse[child] ^= 1; recordMetric('reverseBitFlips'); swap(root, child); } } for (let child = n - 1; child > 0; child--) { join(distinguishedAncestor(child), child); recordMetric('heapBuildPasses'); } for (let end = n - 1; end > 1; end--) { swap(0, end); markIndex(end); recordMetric('extractionPasses'); let node = 1; while ((node << 1) + reverse[node] < end) { node = (node << 1) + reverse[node]; recordMetric('leafWalkSteps'); } while (node > 0) { join(0, node); node >>= 1; if (node > 0) recordMetric('restoreClimbs'); } } compare(0, 1); if (arr[0] > arr[1]) swap(0, 1); markIndex(1); markIndex(0); }
def weakHeapSort(arr, stats): def recordMetric(name, ): metrics[name] = ((metrics[name] or 0) + delta) def swap(i, j): if (i == j): return swap(i, j) value = arr[i] arr[i] = arr[j] arr[j] = value recordMetric("pairSwaps") def markIndex(index): nonlocal finalized markSorted(index) finalized += 1 if (finalized > n): finalized = n checkpoint(finalized, n) def distinguishedAncestor(index): ancestor = index while ((ancestor & 1) == reverse[(ancestor >> 1)]): ancestor >>= 1 recordMetric("ancestorWalkSteps") return (ancestor >> 1) def join(root, child): compare(root, child) recordMetric("joinCalls") if (arr[root] < arr[child]): reverse[child] ^= 1 recordMetric("reverseBitFlips") swap(root, child) if (n < 2): return reverse = [0] * n finalized = 0 metrics.reverseBits = n for child in range((n - 1), 0, -1): join(distinguishedAncestor(child), child) recordMetric("heapBuildPasses") for end in range((n - 1), 1, -1): swap(0, end) markIndex(end) recordMetric("extractionPasses") node = 1 while (((node << 1) + reverse[node]) < end): node = ((node << 1) + reverse[node]) recordMetric("leafWalkSteps") while (node > 0): join(0, node) node >>= 1 if (node > 0): recordMetric("restoreClimbs") compare(0, 1) if (arr[0] > arr[1]): swap(0, 1) markIndex(1) markIndex(0)
#include <vector> #include <algorithm> void recordMetric(int name, int ); void swap(int i, int j); void markIndex(int index); int distinguishedAncestor(int index); void join(int root, int child); void recordMetric(int name, int ) { metrics[name] = (((metrics[name]) != 0 ? (metrics[name]) : (0)) + delta); } void swap(int i, int j) { if((i == j)) { return; } swap(i, j); int value = arr[i]; arr[i] = arr[j]; arr[j] = value; recordMetric("pairSwaps"); } void markIndex(int index) { markSorted(index); finalized++; if((finalized > n)) { finalized = n; } checkpoint(finalized, n); } int distinguishedAncestor(int index) { int ancestor = index; while(((ancestor & 1) == reverse[(ancestor >> 1)])) { ancestor >>= 1; recordMetric("ancestorWalkSteps"); } return (ancestor >> 1); } void join(int root, int child) { compare(root, child); recordMetric("joinCalls"); if((arr[root] < arr[child])) { reverse[child] ^= 1; recordMetric("reverseBitFlips"); swap(root, child); } } void sort(std::vector<int>& arr, int n, int& comparisons, int& swaps) { if((n < 2)) { return; } int reverse = std::vector<int>(n); int metrics = educational.metrics; int finalized = 0; metrics.reverseBits = n; for(int child=(n - 1); child>0; child--) { join(distinguishedAncestor(child), child); recordMetric("heapBuildPasses"); } for(int end=(n - 1); end>1; end--) { swap(0, end); markIndex(end); recordMetric("extractionPasses"); int node = 1; while((((node << 1) + reverse[node]) < end)) { node = ((node << 1) + reverse[node]); recordMetric("leafWalkSteps"); } while((node > 0)) { join(0, node); node >>= 1; if((node > 0)) { recordMetric("restoreClimbs"); } } } compare(0, 1); if((arr[0] > arr[1])) { swap(0, 1); } markIndex(1); markIndex(0); }
void recordMetric(int name, int ) { metrics[name] = (((metrics[name]) != 0 ? (metrics[name]) : (0)) + delta); } void swap(int i, int j) { if((i == j)) { return; } swap(i, j); int value = arr[i]; arr[i] = arr[j]; arr[j] = value; recordMetric("pairSwaps"); } void markIndex(int index) { markSorted(index); finalized++; if((finalized > n)) { finalized = n; } checkpoint(finalized, n); } int distinguishedAncestor(int index) { int ancestor = index; while(((ancestor & 1) == reverse[(ancestor >> 1)])) { ancestor >>= 1; recordMetric("ancestorWalkSteps"); } return (ancestor >> 1); } void join(int root, int child) { compare(root, child); recordMetric("joinCalls"); if((arr[root] < arr[child])) { reverse[child] ^= 1; recordMetric("reverseBitFlips"); swap(root, child); } } public void Sort(int[] arr, int n, dynamic stats) { if((n < 2)) { return; } int reverse = new int[n]; int metrics = stats.educational.metrics; int finalized = 0; metrics.reverseBits = n; for(int child=(n - 1); child>0; child--) { join(distinguishedAncestor(child), child); recordMetric("heapBuildPasses"); } for(int end=(n - 1); end>1; end--) { swap(0, end); markIndex(end); recordMetric("extractionPasses"); int node = 1; while((((node << 1) + reverse[node]) < end)) { node = ((node << 1) + reverse[node]); recordMetric("leafWalkSteps"); } while((node > 0)) { join(0, node); node >>= 1; if((node > 0)) { recordMetric("restoreClimbs"); } } } compare(0, 1); if((arr[0] > arr[1])) { swap(0, 1); } markIndex(1); markIndex(0); }
#include <stdio.h> void recordMetric(int name, int ); void swap(int i, int j); void markIndex(int index); int distinguishedAncestor(int index); void join(int root, int child); void recordMetric(int name, int ) { metrics[name] = (((metrics[name]) != 0 ? (metrics[name]) : (0)) + delta); } void swap(int i, int j) { if((i == j)) { return; } swap(i, j); int value = arr[i]; arr[i] = arr[j]; arr[j] = value; recordMetric("pairSwaps"); } void markIndex(int index) { markSorted(index); finalized++; if((finalized > n)) { finalized = n; } checkpoint(finalized, n); } int distinguishedAncestor(int index) { int ancestor = index; while(((ancestor & 1) == reverse[(ancestor >> 1)])) { ancestor >>= 1; recordMetric("ancestorWalkSteps"); } return (ancestor >> 1); } void join(int root, int child) { compare(root, child); recordMetric("joinCalls"); if((arr[root] < arr[child])) { reverse[child] ^= 1; recordMetric("reverseBitFlips"); swap(root, child); } } void sort(int arr[], int n, int* comparisons, int* swaps) { if((n < 2)) { return; } int reverse = _new_arr_n; int metrics = (*educational).metrics; int finalized = 0; metrics.reverseBits = n; for(int child=(n - 1); child>0; child--) { join(distinguishedAncestor(child), child); recordMetric("heapBuildPasses"); } for(int end=(n - 1); end>1; end--) { swap(0, end); markIndex(end); recordMetric("extractionPasses"); int node = 1; while((((node << 1) + reverse[node]) < end)) { node = ((node << 1) + reverse[node]); recordMetric("leafWalkSteps"); } while((node > 0)) { join(0, node); node >>= 1; if((node > 0)) { recordMetric("restoreClimbs"); } } } compare(0, 1); if((arr[0] > arr[1])) { swap(0, 1); } markIndex(1); markIndex(0); }