github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/sorts/dpsortint/sort.go (about) 1 // 2 // based on http://codeblab.com/wp-content/uploads/2009/09/DualPivotQuicksort.pdf 3 // 4 5 package dpsortint 6 7 const insertionSortThreshold = 27 8 9 func dataequal(data []int, i, k int) bool { return !(dataless(data, i, k) || dataless(data, k, i)) } 10 func dataless(data []int, i, k int) bool { return data[i] < data[k] } 11 func dataswap(data []int, i, k int) { data[i], data[k] = data[k], data[i] } 12 13 func insertionSort(data []int, lo, hi int) { 14 for i := lo + 1; i <= hi; i++ { 15 for k := i; k > lo && dataless(data, k, k-1); k-- { 16 dataswap(data, k, k-1) 17 } 18 } 19 } 20 21 func Sort(data []int) { 22 sortp(data, 0, len(data)-1, 3) 23 } 24 25 func sortp(data []int, left, right int, div int) { 26 n := right - left 27 if n == 0 { 28 return 29 } else if n < insertionSortThreshold { 30 insertionSort(data, left, right) 31 return 32 } 33 34 third := n / div 35 // "medians" 36 m1 := left + third 37 m2 := right - third 38 if m1 <= left { 39 m1 = left + 1 40 } 41 if m2 >= right { 42 m2 = right - 1 43 } 44 45 if dataless(data, m1, m2) { 46 dataswap(data, m1, left) 47 dataswap(data, m2, right) 48 } else { 49 dataswap(data, m1, right) 50 dataswap(data, m2, left) 51 } 52 53 // pointers 54 less := left + 1 55 great := right - 1 56 // sorting 57 for k := less; k <= great; k++ { 58 if dataless(data, k, left) { 59 dataswap(data, k, less) 60 less++ 61 } else if dataless(data, right, k) { 62 for k < great && dataless(data, right, great) { 63 great-- 64 } 65 dataswap(data, k, great) 66 great-- 67 if dataless(data, k, left) { 68 dataswap(data, k, less) 69 less++ 70 } 71 } 72 } 73 74 // swaps 75 dist := great - less 76 if dist < 13 { 77 div++ 78 } 79 80 dataswap(data, less-1, left) 81 dataswap(data, great+1, right) 82 83 // subarrays 84 sortp(data, left, less-2, div) 85 sortp(data, great+2, right, div) 86 87 // equal elements 88 if dist > n-13 && !dataequal(data, left, right) { 89 for k := less; k <= great; k++ { 90 if dataequal(data, k, left) { 91 dataswap(data, k, less) 92 less++ 93 } else if dataequal(data, k, right) { 94 dataswap(data, k, great) 95 great-- 96 if dataequal(data, k, left) { 97 dataswap(data, k, less) 98 less++ 99 } 100 } 101 } 102 } 103 // subarray 104 if dataless(data, left, right) { 105 sortp(data, less, great, div) 106 } 107 }