sort.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  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. // Package sort provides primitives for sorting slices and user-defined
  5. // collections.
  6. package sort
  7. // A type, typically a collection, that satisfies sort.Interface can be
  8. // sorted by the routines in this package. The methods require that the
  9. // elements of the collection be enumerated by an integer index.
  10. type Interface interface {
  11. // Len is the number of elements in the collection.
  12. Len() int
  13. // Less reports whether the element with
  14. // index i should sort before the element with index j.
  15. Less(i, j int) bool
  16. // Swap swaps the elements with indexes i and j.
  17. Swap(i, j int)
  18. }
  19. func min(a, b int) int {
  20. if a < b {
  21. return a
  22. }
  23. return b
  24. }
  25. // Insertion sort
  26. func insertionSort(data Interface, a, b int) {
  27. for i := a + 1; i < b; i++ {
  28. for j := i; j > a && data.Less(j, j-1); j-- {
  29. data.Swap(j, j-1)
  30. }
  31. }
  32. }
  33. // siftDown implements the heap property on data[lo, hi).
  34. // first is an offset into the array where the root of the heap lies.
  35. func siftDown(data Interface, lo, hi, first int) {
  36. root := lo
  37. for {
  38. child := 2*root + 1
  39. if child >= hi {
  40. break
  41. }
  42. if child+1 < hi && data.Less(first+child, first+child+1) {
  43. child++
  44. }
  45. if !data.Less(first+root, first+child) {
  46. return
  47. }
  48. data.Swap(first+root, first+child)
  49. root = child
  50. }
  51. }
  52. func heapSort(data Interface, a, b int) {
  53. first := a
  54. lo := 0
  55. hi := b - a
  56. // Build heap with greatest element at top.
  57. for i := (hi - 1) / 2; i >= 0; i-- {
  58. siftDown(data, i, hi, first)
  59. }
  60. // Pop elements, largest first, into end of data.
  61. for i := hi - 1; i >= 0; i-- {
  62. data.Swap(first, first+i)
  63. siftDown(data, lo, i, first)
  64. }
  65. }
  66. // Quicksort, following Bentley and McIlroy,
  67. // ``Engineering a Sort Function,'' SP&E November 1993.
  68. // medianOfThree moves the median of the three values data[a], data[b], data[c] into data[a].
  69. func medianOfThree(data Interface, a, b, c int) {
  70. m0 := b
  71. m1 := a
  72. m2 := c
  73. // bubble sort on 3 elements
  74. if data.Less(m1, m0) {
  75. data.Swap(m1, m0)
  76. }
  77. if data.Less(m2, m1) {
  78. data.Swap(m2, m1)
  79. }
  80. if data.Less(m1, m0) {
  81. data.Swap(m1, m0)
  82. }
  83. // now data[m0] <= data[m1] <= data[m2]
  84. }
  85. func swapRange(data Interface, a, b, n int) {
  86. for i := 0; i < n; i++ {
  87. data.Swap(a+i, b+i)
  88. }
  89. }
  90. func doPivot(data Interface, lo, hi int) (midlo, midhi int) {
  91. m := lo + (hi-lo)/2 // Written like this to avoid integer overflow.
  92. if hi-lo > 40 {
  93. // Tukey's ``Ninther,'' median of three medians of three.
  94. s := (hi - lo) / 8
  95. medianOfThree(data, lo, lo+s, lo+2*s)
  96. medianOfThree(data, m, m-s, m+s)
  97. medianOfThree(data, hi-1, hi-1-s, hi-1-2*s)
  98. }
  99. medianOfThree(data, lo, m, hi-1)
  100. // Invariants are:
  101. // data[lo] = pivot (set up by ChoosePivot)
  102. // data[lo <= i < a] = pivot
  103. // data[a <= i < b] < pivot
  104. // data[b <= i < c] is unexamined
  105. // data[c <= i < d] > pivot
  106. // data[d <= i < hi] = pivot
  107. //
  108. // Once b meets c, can swap the "= pivot" sections
  109. // into the middle of the slice.
  110. pivot := lo
  111. a, b, c, d := lo+1, lo+1, hi, hi
  112. for {
  113. for b < c {
  114. if data.Less(b, pivot) { // data[b] < pivot
  115. b++
  116. } else if !data.Less(pivot, b) { // data[b] = pivot
  117. data.Swap(a, b)
  118. a++
  119. b++
  120. } else {
  121. break
  122. }
  123. }
  124. for b < c {
  125. if data.Less(pivot, c-1) { // data[c-1] > pivot
  126. c--
  127. } else if !data.Less(c-1, pivot) { // data[c-1] = pivot
  128. data.Swap(c-1, d-1)
  129. c--
  130. d--
  131. } else {
  132. break
  133. }
  134. }
  135. if b >= c {
  136. break
  137. }
  138. // data[b] > pivot; data[c-1] < pivot
  139. data.Swap(b, c-1)
  140. b++
  141. c--
  142. }
  143. n := min(b-a, a-lo)
  144. swapRange(data, lo, b-n, n)
  145. n = min(hi-d, d-c)
  146. swapRange(data, c, hi-n, n)
  147. return lo + b - a, hi - (d - c)
  148. }
  149. func quickSort(data Interface, a, b, maxDepth int) {
  150. for b-a > 7 {
  151. if maxDepth == 0 {
  152. heapSort(data, a, b)
  153. return
  154. }
  155. maxDepth--
  156. mlo, mhi := doPivot(data, a, b)
  157. // Avoiding recursion on the larger subproblem guarantees
  158. // a stack depth of at most lg(b-a).
  159. if mlo-a < b-mhi {
  160. quickSort(data, a, mlo, maxDepth)
  161. a = mhi // i.e., quickSort(data, mhi, b)
  162. } else {
  163. quickSort(data, mhi, b, maxDepth)
  164. b = mlo // i.e., quickSort(data, a, mlo)
  165. }
  166. }
  167. if b-a > 1 {
  168. insertionSort(data, a, b)
  169. }
  170. }
  171. // Sort sorts data.
  172. // It makes one call to data.Len to determine n, and O(n*log(n)) calls to
  173. // data.Less and data.Swap. The sort is not guaranteed to be stable.
  174. func Sort(data Interface) {
  175. // Switch to heapsort if depth of 2*ceil(lg(n+1)) is reached.
  176. n := data.Len()
  177. maxDepth := 0
  178. for i := n; i > 0; i >>= 1 {
  179. maxDepth++
  180. }
  181. maxDepth *= 2
  182. quickSort(data, 0, n, maxDepth)
  183. }
  184. type reverse struct {
  185. // This embedded Interface permits Reverse to use the methods of
  186. // another Interface implementation.
  187. Interface
  188. }
  189. // Less returns the opposite of the embedded implementation's Less method.
  190. func (r reverse) Less(i, j int) bool {
  191. return r.Interface.Less(j, i)
  192. }
  193. // Reverse returns the reverse order for data.
  194. func Reverse(data Interface) Interface {
  195. return &reverse{data}
  196. }
  197. // IsSorted reports whether data is sorted.
  198. func IsSorted(data Interface) bool {
  199. n := data.Len()
  200. for i := n - 1; i > 0; i-- {
  201. if data.Less(i, i-1) {
  202. return false
  203. }
  204. }
  205. return true
  206. }
  207. // Convenience types for common cases
  208. // IntSlice attaches the methods of Interface to []int, sorting in increasing order.
  209. type IntSlice []int
  210. func (p IntSlice) Len() int { return len(p) }
  211. func (p IntSlice) Less(i, j int) bool { return p[i] < p[j] }
  212. func (p IntSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
  213. // Sort is a convenience method.
  214. func (p IntSlice) Sort() { Sort(p) }
  215. // Float64Slice attaches the methods of Interface to []float64, sorting in increasing order.
  216. type Float64Slice []float64
  217. func (p Float64Slice) Len() int { return len(p) }
  218. func (p Float64Slice) Less(i, j int) bool { return p[i] < p[j] || isNaN(p[i]) && !isNaN(p[j]) }
  219. func (p Float64Slice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
  220. // isNaN is a copy of math.IsNaN to avoid a dependency on the math package.
  221. func isNaN(f float64) bool {
  222. return f != f
  223. }
  224. // Sort is a convenience method.
  225. func (p Float64Slice) Sort() { Sort(p) }
  226. // StringSlice attaches the methods of Interface to []string, sorting in increasing order.
  227. type StringSlice []string
  228. func (p StringSlice) Len() int { return len(p) }
  229. func (p StringSlice) Less(i, j int) bool { return p[i] < p[j] }
  230. func (p StringSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
  231. // Sort is a convenience method.
  232. func (p StringSlice) Sort() { Sort(p) }
  233. // Convenience wrappers for common cases
  234. // Ints sorts a slice of ints in increasing order.
  235. func Ints(a []int) { Sort(IntSlice(a)) }
  236. // Float64s sorts a slice of float64s in increasing order.
  237. func Float64s(a []float64) { Sort(Float64Slice(a)) }
  238. // Strings sorts a slice of strings in increasing order.
  239. func Strings(a []string) { Sort(StringSlice(a)) }
  240. // IntsAreSorted tests whether a slice of ints is sorted in increasing order.
  241. func IntsAreSorted(a []int) bool { return IsSorted(IntSlice(a)) }
  242. // Float64sAreSorted tests whether a slice of float64s is sorted in increasing order.
  243. func Float64sAreSorted(a []float64) bool { return IsSorted(Float64Slice(a)) }
  244. // StringsAreSorted tests whether a slice of strings is sorted in increasing order.
  245. func StringsAreSorted(a []string) bool { return IsSorted(StringSlice(a)) }
  246. // Notes on stable sorting:
  247. // The used algorithms are simple and provable correct on all input and use
  248. // only logarithmic additional stack space. They perform well if compared
  249. // experimentally to other stable in-place sorting algorithms.
  250. //
  251. // Remarks on other algorithms evaluated:
  252. // - GCC's 4.6.3 stable_sort with merge_without_buffer from libstdc++:
  253. // Not faster.
  254. // - GCC's __rotate for block rotations: Not faster.
  255. // - "Practical in-place mergesort" from Jyrki Katajainen, Tomi A. Pasanen
  256. // and Jukka Teuhola; Nordic Journal of Computing 3,1 (1996), 27-40:
  257. // The given algorithms are in-place, number of Swap and Assignments
  258. // grow as n log n but the algorithm is not stable.
  259. // - "Fast Stable In-Plcae Sorting with O(n) Data Moves" J.I. Munro and
  260. // V. Raman in Algorithmica (1996) 16, 115-160:
  261. // This algorithm either needs additional 2n bits or works only if there
  262. // are enough different elements available to encode some permutations
  263. // which have to be undone later (so not stable an any input).
  264. // - All the optimal in-place sorting/merging algorithms I found are either
  265. // unstable or rely on enough different elements in each step to encode the
  266. // performed block rearrangements. See also "In-Place Merging Algorithms",
  267. // Denham Coates-Evely, Department of Computer Science, Kings College,
  268. // January 2004 and the reverences in there.
  269. // - Often "optimal" algorithms are optimal in the number of assignments
  270. // but Interface has only Swap as operation.
  271. // Stable sorts data while keeping the original order of equal elements.
  272. //
  273. // It makes one call to data.Len to determine n, O(n*log(n)) calls to
  274. // data.Less and O(n*log(n)*log(n)) calls to data.Swap.
  275. func Stable(data Interface) {
  276. n := data.Len()
  277. blockSize := 20
  278. a, b := 0, blockSize
  279. for b <= n {
  280. insertionSort(data, a, b)
  281. a = b
  282. b += blockSize
  283. }
  284. insertionSort(data, a, n)
  285. for blockSize < n {
  286. a, b = 0, 2*blockSize
  287. for b <= n {
  288. symMerge(data, a, a+blockSize, b)
  289. a = b
  290. b += 2 * blockSize
  291. }
  292. symMerge(data, a, a+blockSize, n)
  293. blockSize *= 2
  294. }
  295. }
  296. // SymMerge merges the two sorted subsequences data[a:m] and data[m:b] using
  297. // the SymMerge algorithm from Pok-Son Kim and Arne Kutzner, "Stable Minimum
  298. // Storage Merging by Symmetric Comparisons", in Susanne Albers and Tomasz
  299. // Radzik, editors, Algorithms - ESA 2004, volume 3221 of Lecture Notes in
  300. // Computer Science, pages 714-723. Springer, 2004.
  301. //
  302. // Let M = m-a and N = b-n. Wolog M < N.
  303. // The recursion depth is bound by ceil(log(N+M)).
  304. // The algorithm needs O(M*log(N/M + 1)) calls to data.Less.
  305. // The algorithm needs O((M+N)*log(M)) calls to data.Swap.
  306. //
  307. // The paper gives O((M+N)*log(M)) as the number of assignments assuming a
  308. // rotation algorithm which uses O(M+N+gcd(M+N)) assignments. The argumentation
  309. // in the paper carries through for Swap operations, especially as the block
  310. // swapping rotate uses only O(M+N) Swaps.
  311. func symMerge(data Interface, a, m, b int) {
  312. if a >= m || m >= b {
  313. return
  314. }
  315. mid := a + (b-a)/2
  316. n := mid + m
  317. start := 0
  318. if m > mid {
  319. start = n - b
  320. r, p := mid, n-1
  321. for start < r {
  322. c := start + (r-start)/2
  323. if !data.Less(p-c, c) {
  324. start = c + 1
  325. } else {
  326. r = c
  327. }
  328. }
  329. } else {
  330. start = a
  331. r, p := m, n-1
  332. for start < r {
  333. c := start + (r-start)/2
  334. if !data.Less(p-c, c) {
  335. start = c + 1
  336. } else {
  337. r = c
  338. }
  339. }
  340. }
  341. end := n - start
  342. rotate(data, start, m, end)
  343. symMerge(data, a, start, mid)
  344. symMerge(data, mid, end, b)
  345. }
  346. // Rotate two consecutives blocks u = data[a:m] and v = data[m:b] in data:
  347. // Data of the form 'x u v y' is changed to 'x v u y'.
  348. // Rotate performs at most b-a many calls to data.Swap.
  349. func rotate(data Interface, a, m, b int) {
  350. i := m - a
  351. if i == 0 {
  352. return
  353. }
  354. j := b - m
  355. if j == 0 {
  356. return
  357. }
  358. if i == j {
  359. swapRange(data, a, m, i)
  360. return
  361. }
  362. p := a + i
  363. for i != j {
  364. if i > j {
  365. swapRange(data, p-i, p, j)
  366. i -= j
  367. } else {
  368. swapRange(data, p-i, p+j-i, i)
  369. j -= i
  370. }
  371. }
  372. swapRange(data, p-i, p, i)
  373. }
  374. /*
  375. Complexity of Stable Sorting
  376. Complexity of block swapping rotation
  377. Each Swap puts one new element into its correct, final position.
  378. Elements which reach their final position are no longer moved.
  379. Thus block swapping rotation needs |u|+|v| calls to Swaps.
  380. This is best possible as each element might need a move.
  381. Pay attention when comparing to other optimal algorithms which
  382. typically count the number of assignments instead of swaps:
  383. E.g. the optimal algorithm of Dudzinski and Dydek for in-place
  384. rotations uses O(u + v + gcd(u,v)) assignments which is
  385. better than our O(3 * (u+v)) as gcd(u,v) <= u.
  386. Stable sorting by SymMerge and BlockSwap rotations
  387. SymMerg complexity for same size input M = N:
  388. Calls to Less: O(M*log(N/M+1)) = O(N*log(2)) = O(N)
  389. Calls to Swap: O((M+N)*log(M)) = O(2*N*log(N)) = O(N*log(N))
  390. (The following argument does not fuzz over a missing -1 or
  391. other stuff which does not impact the final result).
  392. Let n = data.Len(). Assume n = 2^k.
  393. Plain merge sort performs log(n) = k iterations.
  394. On iteration i the algorithm merges 2^(k-i) blocks, each of size 2^i.
  395. Thus iteration i of merge sort performs:
  396. Calls to Less O(2^(k-i) * 2^i) = O(2^k) = O(2^log(n)) = O(n)
  397. Calls to Swap O(2^(k-i) * 2^i * log(2^i)) = O(2^k * i) = O(n*i)
  398. In total k = log(n) iterations are performed; so in total:
  399. Calls to Less O(log(n) * n)
  400. Calls to Swap O(n + 2*n + 3*n + ... + (k-1)*n + k*n)
  401. = O((k/2) * k * n) = O(n * k^2) = O(n * log^2(n))
  402. Above results should generalize to arbitrary n = 2^k + p
  403. and should not be influenced by the initial insertion sort phase:
  404. Insertion sort is O(n^2) on Swap and Less, thus O(bs^2) per block of
  405. size bs at n/bs blocks: O(bs*n) Swaps and Less during insertion sort.
  406. Merge sort iterations start at i = log(bs). With t = log(bs) constant:
  407. Calls to Less O((log(n)-t) * n + bs*n) = O(log(n)*n + (bs-t)*n)
  408. = O(n * log(n))
  409. Calls to Swap O(n * log^2(n) - (t^2+t)/2*n) = O(n * log^2(n))
  410. */