sort.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. //go:generate go run genzfunc.go
  5. // Package sort provides primitives for sorting slices and user-defined collections.
  6. package sort
  7. // An implementation of Interface can be sorted by the routines in this package.
  8. // The methods refer to elements of the underlying collection by integer index.
  9. type Interface interface {
  10. // Len is the number of elements in the collection.
  11. Len() int
  12. // Less reports whether the element with index i
  13. // must sort before the element with index j.
  14. //
  15. // If both Less(i, j) and Less(j, i) are false,
  16. // then the elements at index i and j are considered equal.
  17. // Sort may place equal elements in any order in the final result,
  18. // while Stable preserves the original input order of equal elements.
  19. //
  20. // Less must describe a transitive ordering:
  21. // - if both Less(i, j) and Less(j, k) are true, then Less(i, k) must be true as well.
  22. // - if both Less(i, j) and Less(j, k) are false, then Less(i, k) must be false as well.
  23. //
  24. // Note that floating-point comparison (the < operator on float32 or float64 values)
  25. // is not a transitive ordering when not-a-number (NaN) values are involved.
  26. // See Float64Slice.Less for a correct implementation for floating-point values.
  27. Less(i, j int) bool
  28. // Swap swaps the elements with indexes i and j.
  29. Swap(i, j int)
  30. }
  31. // insertionSort sorts data[a:b] using insertion sort.
  32. func insertionSort(data Interface, a, b int) {
  33. for i := a + 1; i < b; i++ {
  34. for j := i; j > a && data.Less(j, j-1); j-- {
  35. data.Swap(j, j-1)
  36. }
  37. }
  38. }
  39. // siftDown implements the heap property on data[lo:hi].
  40. // first is an offset into the array where the root of the heap lies.
  41. func siftDown(data Interface, lo, hi, first int) {
  42. root := lo
  43. for {
  44. child := 2*root + 1
  45. if child >= hi {
  46. break
  47. }
  48. if child+1 < hi && data.Less(first+child, first+child+1) {
  49. child++
  50. }
  51. if !data.Less(first+root, first+child) {
  52. return
  53. }
  54. data.Swap(first+root, first+child)
  55. root = child
  56. }
  57. }
  58. func heapSort(data Interface, a, b int) {
  59. first := a
  60. lo := 0
  61. hi := b - a
  62. // Build heap with greatest element at top.
  63. for i := (hi - 1) / 2; i >= 0; i-- {
  64. siftDown(data, i, hi, first)
  65. }
  66. // Pop elements, largest first, into end of data.
  67. for i := hi - 1; i >= 0; i-- {
  68. data.Swap(first, first+i)
  69. siftDown(data, lo, i, first)
  70. }
  71. }
  72. // Quicksort, loosely following Bentley and McIlroy,
  73. // ``Engineering a Sort Function,'' SP&E November 1993.
  74. // medianOfThree moves the median of the three values data[m0], data[m1], data[m2] into data[m1].
  75. func medianOfThree(data Interface, m1, m0, m2 int) {
  76. // sort 3 elements
  77. if data.Less(m1, m0) {
  78. data.Swap(m1, m0)
  79. }
  80. // data[m0] <= data[m1]
  81. if data.Less(m2, m1) {
  82. data.Swap(m2, m1)
  83. // data[m0] <= data[m2] && data[m1] < data[m2]
  84. if data.Less(m1, m0) {
  85. data.Swap(m1, m0)
  86. }
  87. }
  88. // now data[m0] <= data[m1] <= data[m2]
  89. }
  90. func swapRange(data Interface, a, b, n int) {
  91. for i := 0; i < n; i++ {
  92. data.Swap(a+i, b+i)
  93. }
  94. }
  95. func doPivot(data Interface, lo, hi int) (midlo, midhi int) {
  96. m := int(uint(lo+hi) >> 1) // Written like this to avoid integer overflow.
  97. if hi-lo > 40 {
  98. // Tukey's ``Ninther,'' median of three medians of three.
  99. s := (hi - lo) / 8
  100. medianOfThree(data, lo, lo+s, lo+2*s)
  101. medianOfThree(data, m, m-s, m+s)
  102. medianOfThree(data, hi-1, hi-1-s, hi-1-2*s)
  103. }
  104. medianOfThree(data, lo, m, hi-1)
  105. // Invariants are:
  106. // data[lo] = pivot (set up by ChoosePivot)
  107. // data[lo < i < a] < pivot
  108. // data[a <= i < b] <= pivot
  109. // data[b <= i < c] unexamined
  110. // data[c <= i < hi-1] > pivot
  111. // data[hi-1] >= pivot
  112. pivot := lo
  113. a, c := lo+1, hi-1
  114. for ; a < c && data.Less(a, pivot); a++ {
  115. }
  116. b := a
  117. for {
  118. for ; b < c && !data.Less(pivot, b); b++ { // data[b] <= pivot
  119. }
  120. for ; b < c && data.Less(pivot, c-1); c-- { // data[c-1] > pivot
  121. }
  122. if b >= c {
  123. break
  124. }
  125. // data[b] > pivot; data[c-1] <= pivot
  126. data.Swap(b, c-1)
  127. b++
  128. c--
  129. }
  130. // If hi-c<3 then there are duplicates (by property of median of nine).
  131. // Let's be a bit more conservative, and set border to 5.
  132. protect := hi-c < 5
  133. if !protect && hi-c < (hi-lo)/4 {
  134. // Lets test some points for equality to pivot
  135. dups := 0
  136. if !data.Less(pivot, hi-1) { // data[hi-1] = pivot
  137. data.Swap(c, hi-1)
  138. c++
  139. dups++
  140. }
  141. if !data.Less(b-1, pivot) { // data[b-1] = pivot
  142. b--
  143. dups++
  144. }
  145. // m-lo = (hi-lo)/2 > 6
  146. // b-lo > (hi-lo)*3/4-1 > 8
  147. // ==> m < b ==> data[m] <= pivot
  148. if !data.Less(m, pivot) { // data[m] = pivot
  149. data.Swap(m, b-1)
  150. b--
  151. dups++
  152. }
  153. // if at least 2 points are equal to pivot, assume skewed distribution
  154. protect = dups > 1
  155. }
  156. if protect {
  157. // Protect against a lot of duplicates
  158. // Add invariant:
  159. // data[a <= i < b] unexamined
  160. // data[b <= i < c] = pivot
  161. for {
  162. for ; a < b && !data.Less(b-1, pivot); b-- { // data[b] == pivot
  163. }
  164. for ; a < b && data.Less(a, pivot); a++ { // data[a] < pivot
  165. }
  166. if a >= b {
  167. break
  168. }
  169. // data[a] == pivot; data[b-1] < pivot
  170. data.Swap(a, b-1)
  171. a++
  172. b--
  173. }
  174. }
  175. // Swap pivot into middle
  176. data.Swap(pivot, b-1)
  177. return b - 1, c
  178. }
  179. func quickSort(data Interface, a, b, maxDepth int) {
  180. for b-a > 12 { // Use ShellSort for slices <= 12 elements
  181. if maxDepth == 0 {
  182. heapSort(data, a, b)
  183. return
  184. }
  185. maxDepth--
  186. mlo, mhi := doPivot(data, a, b)
  187. // Avoiding recursion on the larger subproblem guarantees
  188. // a stack depth of at most lg(b-a).
  189. if mlo-a < b-mhi {
  190. quickSort(data, a, mlo, maxDepth)
  191. a = mhi // i.e., quickSort(data, mhi, b)
  192. } else {
  193. quickSort(data, mhi, b, maxDepth)
  194. b = mlo // i.e., quickSort(data, a, mlo)
  195. }
  196. }
  197. if b-a > 1 {
  198. // Do ShellSort pass with gap 6
  199. // It could be written in this simplified form cause b-a <= 12
  200. for i := a + 6; i < b; i++ {
  201. if data.Less(i, i-6) {
  202. data.Swap(i, i-6)
  203. }
  204. }
  205. insertionSort(data, a, b)
  206. }
  207. }
  208. // Sort sorts data in ascending order as determined by the Less method.
  209. // It makes one call to data.Len to determine n and O(n*log(n)) calls to
  210. // data.Less and data.Swap. The sort is not guaranteed to be stable.
  211. func Sort(data Interface) {
  212. n := data.Len()
  213. quickSort(data, 0, n, maxDepth(n))
  214. }
  215. // maxDepth returns a threshold at which quicksort should switch
  216. // to heapsort. It returns 2*ceil(lg(n+1)).
  217. func maxDepth(n int) int {
  218. var depth int
  219. for i := n; i > 0; i >>= 1 {
  220. depth++
  221. }
  222. return depth * 2
  223. }
  224. // lessSwap is a pair of Less and Swap function for use with the
  225. // auto-generated func-optimized variant of sort.go in
  226. // zfuncversion.go.
  227. type lessSwap struct {
  228. Less func(i, j int) bool
  229. Swap func(i, j int)
  230. }
  231. type reverse struct {
  232. // This embedded Interface permits Reverse to use the methods of
  233. // another Interface implementation.
  234. Interface
  235. }
  236. // Less returns the opposite of the embedded implementation's Less method.
  237. func (r reverse) Less(i, j int) bool {
  238. return r.Interface.Less(j, i)
  239. }
  240. // Reverse returns the reverse order for data.
  241. func Reverse(data Interface) Interface {
  242. return &reverse{data}
  243. }
  244. // IsSorted reports whether data is sorted.
  245. func IsSorted(data Interface) bool {
  246. n := data.Len()
  247. for i := n - 1; i > 0; i-- {
  248. if data.Less(i, i-1) {
  249. return false
  250. }
  251. }
  252. return true
  253. }
  254. // Convenience types for common cases
  255. // IntSlice attaches the methods of Interface to []int, sorting in increasing order.
  256. type IntSlice []int
  257. func (x IntSlice) Len() int { return len(x) }
  258. func (x IntSlice) Less(i, j int) bool { return x[i] < x[j] }
  259. func (x IntSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
  260. // Sort is a convenience method: x.Sort() calls Sort(x).
  261. func (x IntSlice) Sort() { Sort(x) }
  262. // Float64Slice implements Interface for a []float64, sorting in increasing order,
  263. // with not-a-number (NaN) values ordered before other values.
  264. type Float64Slice []float64
  265. func (x Float64Slice) Len() int { return len(x) }
  266. // Less reports whether x[i] should be ordered before x[j], as required by the sort Interface.
  267. // Note that floating-point comparison by itself is not a transitive relation: it does not
  268. // report a consistent ordering for not-a-number (NaN) values.
  269. // This implementation of Less places NaN values before any others, by using:
  270. //
  271. // x[i] < x[j] || (math.IsNaN(x[i]) && !math.IsNaN(x[j]))
  272. //
  273. func (x Float64Slice) Less(i, j int) bool { return x[i] < x[j] || (isNaN(x[i]) && !isNaN(x[j])) }
  274. func (x Float64Slice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
  275. // isNaN is a copy of math.IsNaN to avoid a dependency on the math package.
  276. func isNaN(f float64) bool {
  277. return f != f
  278. }
  279. // Sort is a convenience method: x.Sort() calls Sort(x).
  280. func (x Float64Slice) Sort() { Sort(x) }
  281. // StringSlice attaches the methods of Interface to []string, sorting in increasing order.
  282. type StringSlice []string
  283. func (x StringSlice) Len() int { return len(x) }
  284. func (x StringSlice) Less(i, j int) bool { return x[i] < x[j] }
  285. func (x StringSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
  286. // Sort is a convenience method: x.Sort() calls Sort(x).
  287. func (x StringSlice) Sort() { Sort(x) }
  288. // Convenience wrappers for common cases
  289. // Ints sorts a slice of ints in increasing order.
  290. func Ints(x []int) { Sort(IntSlice(x)) }
  291. // Float64s sorts a slice of float64s in increasing order.
  292. // Not-a-number (NaN) values are ordered before other values.
  293. func Float64s(x []float64) { Sort(Float64Slice(x)) }
  294. // Strings sorts a slice of strings in increasing order.
  295. func Strings(x []string) { Sort(StringSlice(x)) }
  296. // IntsAreSorted reports whether the slice x is sorted in increasing order.
  297. func IntsAreSorted(x []int) bool { return IsSorted(IntSlice(x)) }
  298. // Float64sAreSorted reports whether the slice x is sorted in increasing order,
  299. // with not-a-number (NaN) values before any other values.
  300. func Float64sAreSorted(x []float64) bool { return IsSorted(Float64Slice(x)) }
  301. // StringsAreSorted reports whether the slice x is sorted in increasing order.
  302. func StringsAreSorted(x []string) bool { return IsSorted(StringSlice(x)) }
  303. // Notes on stable sorting:
  304. // The used algorithms are simple and provable correct on all input and use
  305. // only logarithmic additional stack space. They perform well if compared
  306. // experimentally to other stable in-place sorting algorithms.
  307. //
  308. // Remarks on other algorithms evaluated:
  309. // - GCC's 4.6.3 stable_sort with merge_without_buffer from libstdc++:
  310. // Not faster.
  311. // - GCC's __rotate for block rotations: Not faster.
  312. // - "Practical in-place mergesort" from Jyrki Katajainen, Tomi A. Pasanen
  313. // and Jukka Teuhola; Nordic Journal of Computing 3,1 (1996), 27-40:
  314. // The given algorithms are in-place, number of Swap and Assignments
  315. // grow as n log n but the algorithm is not stable.
  316. // - "Fast Stable In-Place Sorting with O(n) Data Moves" J.I. Munro and
  317. // V. Raman in Algorithmica (1996) 16, 115-160:
  318. // This algorithm either needs additional 2n bits or works only if there
  319. // are enough different elements available to encode some permutations
  320. // which have to be undone later (so not stable on any input).
  321. // - All the optimal in-place sorting/merging algorithms I found are either
  322. // unstable or rely on enough different elements in each step to encode the
  323. // performed block rearrangements. See also "In-Place Merging Algorithms",
  324. // Denham Coates-Evely, Department of Computer Science, Kings College,
  325. // January 2004 and the references in there.
  326. // - Often "optimal" algorithms are optimal in the number of assignments
  327. // but Interface has only Swap as operation.
  328. // Stable sorts data in ascending order as determined by the Less method,
  329. // while keeping the original order of equal elements.
  330. //
  331. // It makes one call to data.Len to determine n, O(n*log(n)) calls to
  332. // data.Less and O(n*log(n)*log(n)) calls to data.Swap.
  333. func Stable(data Interface) {
  334. stable(data, data.Len())
  335. }
  336. func stable(data Interface, n int) {
  337. blockSize := 20 // must be > 0
  338. a, b := 0, blockSize
  339. for b <= n {
  340. insertionSort(data, a, b)
  341. a = b
  342. b += blockSize
  343. }
  344. insertionSort(data, a, n)
  345. for blockSize < n {
  346. a, b = 0, 2*blockSize
  347. for b <= n {
  348. symMerge(data, a, a+blockSize, b)
  349. a = b
  350. b += 2 * blockSize
  351. }
  352. if m := a + blockSize; m < n {
  353. symMerge(data, a, m, n)
  354. }
  355. blockSize *= 2
  356. }
  357. }
  358. // symMerge merges the two sorted subsequences data[a:m] and data[m:b] using
  359. // the SymMerge algorithm from Pok-Son Kim and Arne Kutzner, "Stable Minimum
  360. // Storage Merging by Symmetric Comparisons", in Susanne Albers and Tomasz
  361. // Radzik, editors, Algorithms - ESA 2004, volume 3221 of Lecture Notes in
  362. // Computer Science, pages 714-723. Springer, 2004.
  363. //
  364. // Let M = m-a and N = b-n. Wolog M < N.
  365. // The recursion depth is bound by ceil(log(N+M)).
  366. // The algorithm needs O(M*log(N/M + 1)) calls to data.Less.
  367. // The algorithm needs O((M+N)*log(M)) calls to data.Swap.
  368. //
  369. // The paper gives O((M+N)*log(M)) as the number of assignments assuming a
  370. // rotation algorithm which uses O(M+N+gcd(M+N)) assignments. The argumentation
  371. // in the paper carries through for Swap operations, especially as the block
  372. // swapping rotate uses only O(M+N) Swaps.
  373. //
  374. // symMerge assumes non-degenerate arguments: a < m && m < b.
  375. // Having the caller check this condition eliminates many leaf recursion calls,
  376. // which improves performance.
  377. func symMerge(data Interface, a, m, b int) {
  378. // Avoid unnecessary recursions of symMerge
  379. // by direct insertion of data[a] into data[m:b]
  380. // if data[a:m] only contains one element.
  381. if m-a == 1 {
  382. // Use binary search to find the lowest index i
  383. // such that data[i] >= data[a] for m <= i < b.
  384. // Exit the search loop with i == b in case no such index exists.
  385. i := m
  386. j := b
  387. for i < j {
  388. h := int(uint(i+j) >> 1)
  389. if data.Less(h, a) {
  390. i = h + 1
  391. } else {
  392. j = h
  393. }
  394. }
  395. // Swap values until data[a] reaches the position before i.
  396. for k := a; k < i-1; k++ {
  397. data.Swap(k, k+1)
  398. }
  399. return
  400. }
  401. // Avoid unnecessary recursions of symMerge
  402. // by direct insertion of data[m] into data[a:m]
  403. // if data[m:b] only contains one element.
  404. if b-m == 1 {
  405. // Use binary search to find the lowest index i
  406. // such that data[i] > data[m] for a <= i < m.
  407. // Exit the search loop with i == m in case no such index exists.
  408. i := a
  409. j := m
  410. for i < j {
  411. h := int(uint(i+j) >> 1)
  412. if !data.Less(m, h) {
  413. i = h + 1
  414. } else {
  415. j = h
  416. }
  417. }
  418. // Swap values until data[m] reaches the position i.
  419. for k := m; k > i; k-- {
  420. data.Swap(k, k-1)
  421. }
  422. return
  423. }
  424. mid := int(uint(a+b) >> 1)
  425. n := mid + m
  426. var start, r int
  427. if m > mid {
  428. start = n - b
  429. r = mid
  430. } else {
  431. start = a
  432. r = m
  433. }
  434. p := n - 1
  435. for start < r {
  436. c := int(uint(start+r) >> 1)
  437. if !data.Less(p-c, c) {
  438. start = c + 1
  439. } else {
  440. r = c
  441. }
  442. }
  443. end := n - start
  444. if start < m && m < end {
  445. rotate(data, start, m, end)
  446. }
  447. if a < start && start < mid {
  448. symMerge(data, a, start, mid)
  449. }
  450. if mid < end && end < b {
  451. symMerge(data, mid, end, b)
  452. }
  453. }
  454. // rotate rotates two consecutive blocks u = data[a:m] and v = data[m:b] in data:
  455. // Data of the form 'x u v y' is changed to 'x v u y'.
  456. // rotate performs at most b-a many calls to data.Swap,
  457. // and it assumes non-degenerate arguments: a < m && m < b.
  458. func rotate(data Interface, a, m, b int) {
  459. i := m - a
  460. j := b - m
  461. for i != j {
  462. if i > j {
  463. swapRange(data, m-i, m, j)
  464. i -= j
  465. } else {
  466. swapRange(data, m-i, m+j-i, i)
  467. j -= i
  468. }
  469. }
  470. // i == j
  471. swapRange(data, m-i, m, i)
  472. }
  473. /*
  474. Complexity of Stable Sorting
  475. Complexity of block swapping rotation
  476. Each Swap puts one new element into its correct, final position.
  477. Elements which reach their final position are no longer moved.
  478. Thus block swapping rotation needs |u|+|v| calls to Swaps.
  479. This is best possible as each element might need a move.
  480. Pay attention when comparing to other optimal algorithms which
  481. typically count the number of assignments instead of swaps:
  482. E.g. the optimal algorithm of Dudzinski and Dydek for in-place
  483. rotations uses O(u + v + gcd(u,v)) assignments which is
  484. better than our O(3 * (u+v)) as gcd(u,v) <= u.
  485. Stable sorting by SymMerge and BlockSwap rotations
  486. SymMerg complexity for same size input M = N:
  487. Calls to Less: O(M*log(N/M+1)) = O(N*log(2)) = O(N)
  488. Calls to Swap: O((M+N)*log(M)) = O(2*N*log(N)) = O(N*log(N))
  489. (The following argument does not fuzz over a missing -1 or
  490. other stuff which does not impact the final result).
  491. Let n = data.Len(). Assume n = 2^k.
  492. Plain merge sort performs log(n) = k iterations.
  493. On iteration i the algorithm merges 2^(k-i) blocks, each of size 2^i.
  494. Thus iteration i of merge sort performs:
  495. Calls to Less O(2^(k-i) * 2^i) = O(2^k) = O(2^log(n)) = O(n)
  496. Calls to Swap O(2^(k-i) * 2^i * log(2^i)) = O(2^k * i) = O(n*i)
  497. In total k = log(n) iterations are performed; so in total:
  498. Calls to Less O(log(n) * n)
  499. Calls to Swap O(n + 2*n + 3*n + ... + (k-1)*n + k*n)
  500. = O((k/2) * k * n) = O(n * k^2) = O(n * log^2(n))
  501. Above results should generalize to arbitrary n = 2^k + p
  502. and should not be influenced by the initial insertion sort phase:
  503. Insertion sort is O(n^2) on Swap and Less, thus O(bs^2) per block of
  504. size bs at n/bs blocks: O(bs*n) Swaps and Less during insertion sort.
  505. Merge sort iterations start at i = log(bs). With t = log(bs) constant:
  506. Calls to Less O((log(n)-t) * n + bs*n) = O(log(n)*n + (bs-t)*n)
  507. = O(n * log(n))
  508. Calls to Swap O(n * log^2(n) - (t^2+t)/2*n) = O(n * log^2(n))
  509. */