@@ -5,23 +5,23 @@ pub fn asserting_cmp<T: PartialOrd>(a: &T, b: &T) -> std::cmp::Ordering {
5
5
a. partial_cmp ( b) . expect ( "Comparing incomparable elements" )
6
6
}
7
7
8
- /// Assuming slice is totally ordered and sorted , returns the minimum i for which
8
+ /// Assuming slice is sorted and totally ordered , returns the minimum i for which
9
9
/// slice[i] >= key, or slice.len() if no such i exists
10
10
pub fn slice_lower_bound < T : PartialOrd > ( slice : & [ T ] , key : & T ) -> usize {
11
11
slice
12
12
. binary_search_by ( |x| asserting_cmp ( x, key) . then ( std:: cmp:: Ordering :: Greater ) )
13
13
. unwrap_err ( )
14
14
}
15
15
16
- /// Assuming slice is totally ordered and sorted , returns the minimum i for which
16
+ /// Assuming slice is sorted and totally ordered , returns the minimum i for which
17
17
/// slice[i] > key, or slice.len() if no such i exists
18
18
pub fn slice_upper_bound < T : PartialOrd > ( slice : & [ T ] , key : & T ) -> usize {
19
19
slice
20
20
. binary_search_by ( |x| asserting_cmp ( x, key) . then ( std:: cmp:: Ordering :: Less ) )
21
21
. unwrap_err ( )
22
22
}
23
23
24
- /// Merge two sorted collections into one
24
+ /// Merge two sorted and totally ordered collections into one
25
25
pub fn merge_sorted < T : PartialOrd > (
26
26
i1 : impl IntoIterator < Item = T > ,
27
27
i2 : impl IntoIterator < Item = T > ,
@@ -35,6 +35,16 @@ pub fn merge_sorted<T: PartialOrd>(
35
35
merged
36
36
}
37
37
38
+ /// A stable sort
39
+ pub fn merge_sort < T : Ord > ( mut v : Vec < T > ) -> Vec < T > {
40
+ if v. len ( ) < 2 {
41
+ v
42
+ } else {
43
+ let v2 = v. split_off ( v. len ( ) / 2 ) ;
44
+ merge_sorted ( merge_sort ( v) , merge_sort ( v2) )
45
+ }
46
+ }
47
+
38
48
/// A simple data structure for coordinate compression
39
49
pub struct SparseIndex {
40
50
coords : Vec < i64 > ,
@@ -58,9 +68,9 @@ impl SparseIndex {
58
68
/// Represents a maximum (upper envelope) of a collection of linear functions of a variable,
59
69
/// evaluated using the convex hull trick with square root decomposition.
60
70
pub struct PiecewiseLinearFn {
71
+ recent_lines : Vec < ( f64 , f64 ) > ,
61
72
sorted_lines : Vec < ( f64 , f64 ) > ,
62
73
intersections : Vec < f64 > ,
63
- recent_lines : Vec < ( f64 , f64 ) > ,
64
74
merge_threshold : usize ,
65
75
}
66
76
@@ -70,9 +80,9 @@ impl PiecewiseLinearFn {
70
80
/// any threshold less than N (e.g., 0) yields O(N + Q log N) time complexity.
71
81
pub fn with_merge_threshold ( merge_threshold : usize ) -> Self {
72
82
Self {
83
+ recent_lines : vec ! [ ] ,
73
84
sorted_lines : vec ! [ ] ,
74
85
intersections : vec ! [ ] ,
75
- recent_lines : vec ! [ ] ,
76
86
merge_threshold,
77
87
}
78
88
}
@@ -155,6 +165,15 @@ mod test {
155
165
assert_eq ! ( merge_sorted( vals1, vals2) , vals_merged) ;
156
166
}
157
167
168
+ #[ test]
169
+ fn test_merge_sort ( ) {
170
+ let unsorted = vec ! [ 8 , -5 , 1 , 4 , -3 , 4 ] ;
171
+ let sorted = vec ! [ -5 , -3 , 1 , 4 , 4 , 8 ] ;
172
+
173
+ assert_eq ! ( merge_sort( unsorted) , sorted) ;
174
+ assert_eq ! ( merge_sort( sorted. clone( ) ) , sorted) ;
175
+ }
176
+
158
177
#[ test]
159
178
fn test_coord_compress ( ) {
160
179
let mut coords = vec ! [ 16 , 99 , 45 , 18 ] ;
0 commit comments