26
26
/// ```
27
27
pub fn [T : Compare ] sort (self : Array [T ]) -> Unit {
28
28
let len = self .length ()
29
- quick_sort (self [: len ] , None , get_limit (len ))
29
+ quick_sort ({ array : self , start : 0 , end : len } , None , get_limit (len ))
30
30
}
31
31
32
32
///|
33
- fn [T : Compare ] quick_sort (arr : ArrayView [T ], pred : T? , limit : Int ) -> Unit {
33
+ fn [T : Compare ] quick_sort (arr : ArraySlice [T ], pred : T? , limit : Int ) -> Unit {
34
34
let mut limit = limit
35
35
let mut arr = arr
36
36
let mut pred = pred
@@ -41,7 +41,7 @@ fn[T : Compare] quick_sort(arr : ArrayView[T], pred : T?, limit : Int) -> Unit {
41
41
let len = arr .length ()
42
42
if len <= insertion_sort_len {
43
43
if len >= 2 {
44
- ArrayView :: insertion_sort (arr )
44
+ insertion_sort (arr )
45
45
}
46
46
return
47
47
}
@@ -60,7 +60,10 @@ fn[T : Compare] quick_sort(arr : ArrayView[T], pred : T?, limit : Int) -> Unit {
60
60
}
61
61
let (pivot , partitioned ) = partition (arr , pivot_index )
62
62
was_partitioned = partitioned
63
- balanced = minimum (pivot , len - pivot ) >= len / 8
63
+ balanced = {
64
+ let diff = len - pivot
65
+ (if pivot < diff { pivot } else { diff }) >= len / 8
66
+ }
64
67
if !balanced {
65
68
limit - = 1
66
69
}
@@ -107,7 +110,7 @@ fn get_limit(len : Int) -> Int {
107
110
/// It will only tolerate at most 8 unsorted elements. The time complexity is O(n).
108
111
///
109
112
/// Returns whether the array is sorted.
110
- fn [T : Compare ] try_bubble_sort (arr : ArrayView [T ]) -> Bool {
113
+ fn [T : Compare ] try_bubble_sort (arr : ArraySlice [T ]) -> Bool {
111
114
let max_tries = 8
112
115
let mut tries = 0
113
116
for i in 1 ..< arr .length () {
@@ -128,7 +131,7 @@ fn[T : Compare] try_bubble_sort(arr : ArrayView[T]) -> Bool {
128
131
129
132
///|
130
133
/// Used when the array is small enough (<=16) to avoid recursion overhead.
131
- fn [T : Compare ] ArrayView :: insertion_sort (arr : ArrayView [T ]) -> Unit {
134
+ fn [T : Compare ] insertion_sort (arr : ArraySlice [T ]) -> Unit {
132
135
for i in 1 ..< arr .length () {
133
136
for j = i ; j > 0 && arr [j - 1 ] > arr [j ]; j = j - 1 {
134
137
arr .swap (j , j - 1 )
@@ -137,7 +140,10 @@ fn[T : Compare] ArrayView::insertion_sort(arr : ArrayView[T]) -> Unit {
137
140
}
138
141
139
142
///|
140
- fn [T : Compare ] partition (arr : ArrayView [T ], pivot_index : Int ) -> (Int , Bool ) {
143
+ fn [T : Compare ] partition (
144
+ arr : ArraySlice [T ],
145
+ pivot_index : Int ,
146
+ ) -> (Int , Bool ) {
141
147
arr .swap (pivot_index , arr .length () - 1 )
142
148
let pivot = arr [arr .length () - 1 ]
143
149
let mut i = 0
@@ -161,7 +167,7 @@ fn[T : Compare] partition(arr : ArrayView[T], pivot_index : Int) -> (Int, Bool)
161
167
/// It avoids worst case performance by choosing a pivot that is likely to be close to the median.
162
168
///
163
169
/// Returns the pivot index and whether the array is likely sorted.
164
- fn [T : Compare ] choose_pivot (arr : ArrayView [T ]) -> (Int , Bool ) {
170
+ fn [T : Compare ] choose_pivot (arr : ArraySlice [T ]) -> (Int , Bool ) {
165
171
let len = arr .length ()
166
172
let use_median_of_medians = 50
167
173
let max_swaps = 4 * 3
@@ -195,7 +201,7 @@ fn[T : Compare] choose_pivot(arr : ArrayView[T]) -> (Int, Bool) {
195
201
}
196
202
197
203
///|
198
- fn [T : Compare ] heap_sort (arr : ArrayView [T ]) -> Unit {
204
+ fn [T : Compare ] heap_sort (arr : ArraySlice [T ]) -> Unit {
199
205
let len = arr .length ()
200
206
for i = len / 2 - 1 ; i >= 0 ; i = i - 1 {
201
207
sift_down (arr , i )
@@ -207,7 +213,7 @@ fn[T : Compare] heap_sort(arr : ArrayView[T]) -> Unit {
207
213
}
208
214
209
215
///|
210
- fn [T : Compare ] sift_down (arr : ArrayView [T ], index : Int ) -> Unit {
216
+ fn [T : Compare ] sift_down (arr : ArraySlice [T ], index : Int ) -> Unit {
211
217
let mut index = index
212
218
let len = arr .length ()
213
219
let mut child = index * 2 + 1
@@ -253,19 +259,19 @@ fn test_sort(f : (Array[Int]) -> Unit) -> Unit raise {
253
259
///|
254
260
test "try_bubble_sort" {
255
261
let arr = [8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 ]
256
- let sorted = try_bubble_sort (arr [ 0 : 8 ] )
262
+ let sorted = try_bubble_sort ({ array : arr , start : 0 , end : 8 } )
257
263
inspect (sorted , content = "true" )
258
264
assert_eq (arr , [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ])
259
265
}
260
266
261
267
///|
262
268
test "heap_sort" {
263
- test_sort (arr => heap_sort (arr [:] ))
269
+ test_sort (arr => heap_sort ({ array : arr , start : 0 , end : arr . length () } ))
264
270
}
265
271
266
272
///|
267
273
test "insertion_sort" {
268
- test_sort (arr => ArrayView :: insertion_sort (arr [:] ))
274
+ test_sort (arr => insertion_sort ({ array : arr , start : 0 , end : arr . length () } ))
269
275
}
270
276
271
277
///|
@@ -287,29 +293,29 @@ test "sort with same pivot optimization" {
287
293
///|
288
294
test "heap_sort coverage" {
289
295
let arr = [5 , 4 , 3 , 2 , 1 ]
290
- heap_sort (arr [:] )
296
+ heap_sort ({ array : arr , start : 0 , end : arr . length () } )
291
297
assert_eq (arr , [1 , 2 , 3 , 4 , 5 ])
292
298
let arr2 = [1 , 2 , 3 , 4 , 5 ]
293
- heap_sort (arr2 [:] )
299
+ heap_sort ({ array : arr2 , start : 0 , end : arr2 . length () } )
294
300
assert_eq (arr2 , [1 , 2 , 3 , 4 , 5 ])
295
301
let arr2 = [1 , 2 , 3 , 4 , 5 ]
296
- heap_sort (arr2 [:] )
302
+ heap_sort ({ array : arr2 , start : 0 , end : arr2 . length () } )
297
303
assert_eq (arr2 , [1 , 2 , 3 , 4 , 5 ])
298
304
let arr3 = [5 , 5 , 5 , 5 , 1 ]
299
- heap_sort (arr3 [:] )
305
+ heap_sort ({ array : arr3 , start : 0 , end : arr3 . length () } )
300
306
assert_eq (arr3 , [1 , 5 , 5 , 5 , 5 ])
301
307
}
302
308
303
309
///|
304
310
test "quick_sort limit check" {
305
311
let arr = [5 , 4 , 3 , 2 , 1 ]
306
- quick_sort (arr [:] , None , 0 )
312
+ quick_sort ({ array : arr , start : 0 , end : arr . length () } , None , 0 )
307
313
assert_eq (arr , [1 , 2 , 3 , 4 , 5 ])
308
314
let arr2 = [1 , 2 , 3 , 4 , 5 ]
309
- quick_sort (arr2 [:] , None , 0 )
315
+ quick_sort ({ array : arr2 , start : 0 , end : arr2 . length () } , None , 0 )
310
316
assert_eq (arr2 , [1 , 2 , 3 , 4 , 5 ])
311
317
let arr3 = [5 , 5 , 5 , 5 , 1 ]
312
- quick_sort (arr3 [:] , None , 0 )
318
+ quick_sort ({ array : arr3 , start : 0 , end : arr3 . length () } , None , 0 )
313
319
assert_eq (arr3 , [1 , 5 , 5 , 5 , 5 ])
314
320
}
315
321
@@ -319,16 +325,16 @@ test "quick_sort with pred check" {
319
325
for i = 16 ; i >= 0 ; i = i - 1 {
320
326
arr .push (i )
321
327
}
322
- quick_sort (arr [:] , Some (8 ), 0 )
328
+ quick_sort ({ array : arr , start : 0 , end : arr . length () } , Some (8 ), 0 )
323
329
assert_eq (arr , [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 ])
324
330
let arr = [5 , 4 , 3 , 2 , 1 ]
325
- quick_sort (arr [:] , Some (3 ), 0 )
331
+ quick_sort ({ array : arr , start : 0 , end : arr . length () } , Some (3 ), 0 )
326
332
assert_eq (arr , [1 , 2 , 3 , 4 , 5 ])
327
333
let arr2 = [1 , 2 , 3 , 4 , 5 ]
328
- quick_sort (arr2 [:] , Some (3 ), 0 )
334
+ quick_sort ({ array : arr2 , start : 0 , end : arr2 . length () } , Some (3 ), 0 )
329
335
assert_eq (arr2 , [1 , 2 , 3 , 4 , 5 ])
330
336
let arr3 = [5 , 5 , 5 , 5 , 1 ]
331
- quick_sort (arr3 [:] , Some (3 ), 0 )
337
+ quick_sort ({ array : arr3 , start : 0 , end : arr3 . length () } , Some (3 ), 0 )
332
338
assert_eq (arr3 , [1 , 5 , 5 , 5 , 5 ])
333
339
}
334
340
@@ -338,36 +344,36 @@ test "quick_sort with unbalanced partitions" {
338
344
for i = 16 ; i >= 0 ; i = i - 1 {
339
345
arr .push (if i >= 8 { i } else { 8 })
340
346
}
341
- quick_sort (arr [:] , Some (8 ), 42 )
347
+ quick_sort ({ array : arr , start : 0 , end : arr . length () } , Some (8 ), 42 )
342
348
assert_eq (arr , [8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 , 16 ])
343
349
let arr = [5 , 4 , 3 , 2 , 1 ]
344
- quick_sort (arr [:] , None , 1 )
350
+ quick_sort ({ array : arr , start : 0 , end : arr . length () } , None , 1 )
345
351
assert_eq (arr , [1 , 2 , 3 , 4 , 5 ])
346
352
let arr2 = [1 , 2 , 3 , 4 , 5 ]
347
- quick_sort (arr2 [:] , None , 1 )
353
+ quick_sort ({ array : arr2 , start : 0 , end : arr2 . length () } , None , 1 )
348
354
assert_eq (arr2 , [1 , 2 , 3 , 4 , 5 ])
349
355
let arr3 = [5 , 5 , 5 , 5 , 1 ]
350
- quick_sort (arr3 [:] , None , 1 )
356
+ quick_sort ({ array : arr3 , start : 0 , end : arr3 . length () } , None , 1 )
351
357
assert_eq (arr3 , [1 , 5 , 5 , 5 , 5 ])
352
358
}
353
359
354
360
///|
355
361
test "quick_sort with pivot equal to pred" {
356
362
let arr = [5 , 4 , 3 , 2 , 1 ]
357
- quick_sort (arr [:] , Some (3 ), 0 )
363
+ quick_sort ({ array : arr , start : 0 , end : arr . length () } , Some (3 ), 0 )
358
364
assert_eq (arr , [1 , 2 , 3 , 4 , 5 ])
359
365
}
360
366
361
367
///|
362
368
test "quick_sort with pred less than all elements" {
363
369
let arr = [5 , 4 , 3 , 2 , 1 ]
364
- quick_sort (arr [:] , Some (0 ), 0 )
370
+ quick_sort ({ array : arr , start : 0 , end : arr . length () } , Some (0 ), 0 )
365
371
assert_eq (arr , [1 , 2 , 3 , 4 , 5 ])
366
372
}
367
373
368
374
///|
369
375
test "quick_sort with pred greater than all elements" {
370
376
let arr = [5 , 4 , 3 , 2 , 1 ]
371
- quick_sort (arr [:] , Some (6 ), 0 )
377
+ quick_sort ({ array : arr , start : 0 , end : arr . length () } , Some (6 ), 0 )
372
378
assert_eq (arr , [1 , 2 , 3 , 4 , 5 ])
373
379
}
0 commit comments