github.com/egonelbre/exp@v0.0.0-20240430123955-ed1d3aa93911/sentinels/partition.go (about) 1 package sentinels 2 3 // requires -gcflags="-B" to be effective 4 func PartitionBreak(items []int, pivot int) int { 5 items[pivot], items[0] = items[0], items[pivot] 6 lo, hi := 1, len(items)-1 7 loop: 8 for ; ; lo, hi = lo+1, hi-1 { 9 for ; ; lo++ { 10 if lo > hi { 11 break loop 12 } 13 if items[lo] >= items[0] { 14 break 15 } 16 } 17 for ; ; hi-- { 18 if lo >= hi { 19 break loop 20 } 21 if items[0] >= items[hi] { 22 break 23 } 24 } 25 items[hi], items[lo] = items[lo], items[hi] 26 } 27 lo-- 28 items[lo], items[0] = items[0], items[lo] 29 return lo 30 } 31 32 // requires -gcflags="-B" to be effective 33 func PartitionSentinel(items []int, pivot int) int { 34 if len(items) <= 1 { 35 return 0 36 } 37 items[pivot], items[0] = items[0], items[pivot] 38 39 pv, save := items[0], items[0] 40 save, items[len(items)-1] = items[len(items)-1], save 41 42 lo, hi := 0, len(items)-1 43 for { 44 for { 45 lo++ 46 if items[lo] < pv { 47 break 48 } 49 } 50 items[hi] = items[lo] 51 for { 52 hi-- 53 if items[hi] >= pv { 54 break 55 } 56 } 57 if lo >= hi { 58 break 59 } 60 items[lo] = items[hi] 61 } 62 63 if lo == hi+2 { 64 items[lo] = items[hi+1] 65 lo-- 66 } 67 items[lo] = save 68 if pv < save { 69 lo-- 70 } 71 items[lo], items[0] = items[0], items[lo] 72 return lo 73 }