@@ -102,6 +102,26 @@ fn partition_at_index_loop<'a, T, F>(
102
102
}
103
103
}
104
104
105
+ /// Helper function that returns the index of the minimum element in the slice using the given
106
+ /// comparator function
107
+ fn min_index < T , F : FnMut ( & T , & T ) -> bool > ( slice : & [ T ] , is_less : & mut F ) -> Option < usize > {
108
+ slice
109
+ . iter ( )
110
+ . enumerate ( )
111
+ . reduce ( |acc, t| if is_less ( t. 1 , acc. 1 ) { t } else { acc } )
112
+ . map ( |( i, _) | i)
113
+ }
114
+
115
+ /// Helper function that returns the index of the maximum element in the slice using the given
116
+ /// comparator function
117
+ fn max_index < T , F : FnMut ( & T , & T ) -> bool > ( slice : & [ T ] , is_less : & mut F ) -> Option < usize > {
118
+ slice
119
+ . iter ( )
120
+ . enumerate ( )
121
+ . reduce ( |acc, t| if is_less ( acc. 1 , t. 1 ) { t } else { acc } )
122
+ . map ( |( i, _) | i)
123
+ }
124
+
105
125
/// Reorder the slice such that the element at `index` is at its final sorted position.
106
126
pub fn partition_at_index < T , F > (
107
127
v : & mut [ T ] ,
@@ -120,13 +140,13 @@ where
120
140
} else if index == v. len ( ) - 1 {
121
141
// Find max element and place it in the last position of the array. We're free to use
122
142
// `unwrap()` here because we know v must not be empty.
123
- let ( max_index , _ ) = v . iter ( ) . enumerate ( ) . max_by ( from_is_less ( & mut is_less) ) . unwrap ( ) ;
124
- v. swap ( max_index , index) ;
143
+ let max_idx = max_index ( v , & mut is_less) . unwrap ( ) ;
144
+ v. swap ( max_idx , index) ;
125
145
} else if index == 0 {
126
146
// Find min element and place it in the first position of the array. We're free to use
127
147
// `unwrap()` here because we know v must not be empty.
128
- let ( min_index , _ ) = v . iter ( ) . enumerate ( ) . min_by ( from_is_less ( & mut is_less) ) . unwrap ( ) ;
129
- v. swap ( min_index , index) ;
148
+ let min_idx = min_index ( v , & mut is_less) . unwrap ( ) ;
149
+ v. swap ( min_idx , index) ;
130
150
} else {
131
151
partition_at_index_loop ( v, index, & mut is_less, None ) ;
132
152
}
@@ -137,16 +157,6 @@ where
137
157
( left, pivot, right)
138
158
}
139
159
140
- /// helper function used to find the index of the min/max element
141
- /// using e.g. `slice.iter().enumerate().min_by(from_is_less(&mut is_less)).unwrap()`
142
- fn from_is_less < T > (
143
- is_less : & mut impl FnMut ( & T , & T ) -> bool ,
144
- ) -> impl FnMut ( & ( usize , & T ) , & ( usize , & T ) ) -> cmp:: Ordering + ' _ {
145
- |& ( _, x) , & ( _, y) | {
146
- if is_less ( x, y) { cmp:: Ordering :: Less } else { cmp:: Ordering :: Greater }
147
- }
148
- }
149
-
150
160
/// Selection algorithm to select the k-th element from the slice in guaranteed O(n) time.
151
161
/// This is essentially a quickselect that uses Tukey's Ninther for pivot selection
152
162
fn median_of_medians < T , F : FnMut ( & T , & T ) -> bool > ( mut v : & mut [ T ] , is_less : & mut F , mut k : usize ) {
@@ -170,14 +180,14 @@ fn median_of_medians<T, F: FnMut(&T, &T) -> bool>(mut v: &mut [T], is_less: &mut
170
180
if k == v. len ( ) - 1 {
171
181
// Find max element and place it in the last position of the array. We're free to use
172
182
// `unwrap()` here because we know v must not be empty.
173
- let ( max_index , _ ) = v . iter ( ) . enumerate ( ) . max_by ( from_is_less ( is_less) ) . unwrap ( ) ;
174
- v. swap ( max_index , k) ;
183
+ let max_idx = max_index ( v , is_less) . unwrap ( ) ;
184
+ v. swap ( max_idx , k) ;
175
185
return ;
176
186
} else if k == 0 {
177
187
// Find min element and place it in the first position of the array. We're free to use
178
188
// `unwrap()` here because we know v must not be empty.
179
- let ( min_index , _ ) = v . iter ( ) . enumerate ( ) . min_by ( from_is_less ( is_less) ) . unwrap ( ) ;
180
- v. swap ( min_index , k) ;
189
+ let min_idx = min_index ( v , is_less) . unwrap ( ) ;
190
+ v. swap ( min_idx , k) ;
181
191
return ;
182
192
}
183
193
0 commit comments