4
4
5
5
package slices
6
6
7
- import "golang.org/x/exp/constraints"
7
+ import (
8
+ "math/bits"
9
+
10
+ "golang.org/x/exp/constraints"
11
+ )
8
12
9
13
// Sort sorts a slice of any ordered type in ascending order.
14
+ // Sort may fail to sort correctly when sorting slices of floating-point
15
+ // numbers containing Not-a-number (NaN) values.
16
+ // Use slices.SortFunc(x, func(a, b float64) bool {return a < b || (math.IsNaN(a) && !math.IsNaN(b))})
17
+ // instead if the input may contain NaNs.
10
18
func Sort [E constraints.Ordered ](x []E ) {
11
19
n := len (x )
12
- quickSortOrdered (x , 0 , n , maxDepth ( n ))
20
+ pdqsortOrdered (x , 0 , n , bits . Len ( uint ( n ) ))
13
21
}
14
22
15
- // Sort sorts the slice x in ascending order as determined by the less function.
23
+ // SortFunc sorts the slice x in ascending order as determined by the less function.
16
24
// This sort is not guaranteed to be stable.
25
+ //
26
+ // SortFunc requires that less is a strict weak ordering.
27
+ // See https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings.
17
28
func SortFunc [E any ](x []E , less func (a , b E ) bool ) {
18
29
n := len (x )
19
- quickSortLessFunc (x , 0 , n , maxDepth ( n ), less )
30
+ pdqsortLessFunc (x , 0 , n , bits . Len ( uint ( n ) ), less )
20
31
}
21
32
22
33
// SortStable sorts the slice x while keeping the original order of equal
@@ -76,16 +87,6 @@ func BinarySearchFunc[E any](x []E, target E, cmp func(E, E) int) (int, bool) {
76
87
}
77
88
}
78
89
79
- // maxDepth returns a threshold at which quicksort should switch
80
- // to heapsort. It returns 2*ceil(lg(n+1)).
81
- func maxDepth (n int ) int {
82
- var depth int
83
- for i := n ; i > 0 ; i >>= 1 {
84
- depth ++
85
- }
86
- return depth * 2
87
- }
88
-
89
90
func search (n int , f func (int ) bool ) int {
90
91
// Define f(-1) == false and f(n) == true.
91
92
// Invariant: f(i-1) == false, f(j) == true.
@@ -102,3 +103,25 @@ func search(n int, f func(int) bool) int {
102
103
// i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i.
103
104
return i
104
105
}
106
+
107
+ type sortedHint int // hint for pdqsort when choosing the pivot
108
+
109
+ const (
110
+ unknownHint sortedHint = iota
111
+ increasingHint
112
+ decreasingHint
113
+ )
114
+
115
+ // xorshift paper: https://www.jstatsoft.org/article/view/v008i14/xorshift.pdf
116
+ type xorshift uint64
117
+
118
+ func (r * xorshift ) Next () uint64 {
119
+ * r ^= * r << 13
120
+ * r ^= * r >> 17
121
+ * r ^= * r << 5
122
+ return uint64 (* r )
123
+ }
124
+
125
+ func nextPowerOfTwo (length int ) uint {
126
+ return 1 << bits .Len (uint (length ))
127
+ }
0 commit comments