1
1
using System ;
2
2
using System . Collections . Generic ;
3
+ using Algorithms . Sorters . Utils ;
3
4
4
5
namespace Algorithms . Sorters . Comparison ;
5
6
@@ -163,15 +164,6 @@ private static void ReverseRange(T[] array, int start, int end)
163
164
}
164
165
}
165
166
166
- /// <summary>
167
- /// Left shift a value, preventing a roll over to negative numbers.
168
- /// </summary>
169
- /// <param name="shiftable">int value to left shift.</param>
170
- /// <returns>Left shifted value, bound to 2,147,483,647.</returns>
171
- private static int BoundLeftShift ( int shiftable ) => ( shiftable << 1 ) < 0
172
- ? ( shiftable << 1 ) + 1
173
- : int . MaxValue ;
174
-
175
167
/// <summary>
176
168
/// Check the chunks before getting in to a merge to make sure there's something to actually do.
177
169
/// </summary>
@@ -270,105 +262,6 @@ private int CountRunAndMakeAscending(T[] array, int start)
270
262
return runHi - start ;
271
263
}
272
264
273
- /// <summary>
274
- /// Find the position in the array that a key should fit to the left of where it currently sits.
275
- /// </summary>
276
- /// <param name="array">Array to search.</param>
277
- /// <param name="key">Key to place in the array.</param>
278
- /// <param name="i">Base index for the key.</param>
279
- /// <param name="len">Length of the chunk to run through.</param>
280
- /// <param name="hint">Initial starting position to start from.</param>
281
- /// <returns>Offset for the key's location.</returns>
282
- private int GallopLeft ( T [ ] array , T key , int i , int len , int hint )
283
- {
284
- var ( offset , lastOfs ) = comparer . Compare ( key , array [ i + hint ] ) > 0
285
- ? RightRun ( array , key , i , len , hint , 0 )
286
- : LeftRun ( array , key , i , hint , 1 ) ;
287
-
288
- return FinalOffset ( array , key , i , offset , lastOfs , 1 ) ;
289
- }
290
-
291
- /// <summary>
292
- /// Find the position in the array that a key should fit to the right of where it currently sits.
293
- /// </summary>
294
- /// <param name="array">Array to search.</param>
295
- /// <param name="key">Key to place in the array.</param>
296
- /// <param name="i">Base index for the key.</param>
297
- /// <param name="len">Length of the chunk to run through.</param>
298
- /// <param name="hint">Initial starting position to start from.</param>
299
- /// <returns>Offset for the key's location.</returns>
300
- private int GallopRight ( T [ ] array , T key , int i , int len , int hint )
301
- {
302
- var ( offset , lastOfs ) = comparer . Compare ( key , array [ i + hint ] ) < 0
303
- ? LeftRun ( array , key , i , hint , 0 )
304
- : RightRun ( array , key , i , len , hint , - 1 ) ;
305
-
306
- return FinalOffset ( array , key , i , offset , lastOfs , 0 ) ;
307
- }
308
-
309
- private ( int offset , int lastOfs ) LeftRun ( T [ ] array , T key , int i , int hint , int lt )
310
- {
311
- var maxOfs = hint + 1 ;
312
- var ( offset , tmp ) = ( 1 , 0 ) ;
313
-
314
- while ( offset < maxOfs && comparer . Compare ( key , array [ i + hint - offset ] ) < lt )
315
- {
316
- tmp = offset ;
317
- offset = BoundLeftShift ( offset ) ;
318
- }
319
-
320
- if ( offset > maxOfs )
321
- {
322
- offset = maxOfs ;
323
- }
324
-
325
- var lastOfs = hint - offset ;
326
- offset = hint - tmp ;
327
-
328
- return ( offset , lastOfs ) ;
329
- }
330
-
331
- private ( int offset , int lastOfs ) RightRun ( T [ ] array , T key , int i , int len , int hint , int gt )
332
- {
333
- var ( offset , lastOfs ) = ( 1 , 0 ) ;
334
- var maxOfs = len - hint ;
335
- while ( offset < maxOfs && comparer . Compare ( key , array [ i + hint + offset ] ) > gt )
336
- {
337
- lastOfs = offset ;
338
- offset = BoundLeftShift ( offset ) ;
339
- }
340
-
341
- if ( offset > maxOfs )
342
- {
343
- offset = maxOfs ;
344
- }
345
-
346
- offset += hint ;
347
- lastOfs += hint ;
348
-
349
- return ( offset , lastOfs ) ;
350
- }
351
-
352
- private int FinalOffset ( T [ ] array , T key , int i , int offset , int lastOfs , int lt )
353
- {
354
- lastOfs ++ ;
355
- while ( lastOfs < offset )
356
- {
357
- var m = lastOfs + ( int ) ( ( uint ) ( offset - lastOfs ) >> 1 ) ;
358
-
359
- if ( comparer . Compare ( key , array [ i + m ] ) < lt )
360
- {
361
- offset = m ;
362
- }
363
- else
364
- {
365
- lastOfs = m + 1 ;
366
- }
367
- }
368
-
369
- return offset ;
370
- }
371
-
372
265
/// <summary>
373
266
/// Sorts the specified portion of the specified array using a binary
374
267
/// insertion sort. It requires O(n log n) compares, but O(n^2) data movement.
@@ -470,7 +363,7 @@ private void MergeAt(T[] array, int index)
470
363
471
364
stackSize -- ;
472
365
473
- var k = GallopRight ( array , array [ baseB ] , baseA , lenA , 0 ) ;
366
+ var k = GallopingStrategy < T > . GallopRight ( array , array [ baseB ] , baseA , lenA , comparer ) ;
474
367
475
368
baseA += k ;
476
369
lenA -= k ;
@@ -480,7 +373,7 @@ private void MergeAt(T[] array, int index)
480
373
return ;
481
374
}
482
375
483
- lenB = GallopLeft ( array , array [ baseA + lenA - 1 ] , baseB , lenB , lenB - 1 ) ;
376
+ lenB = GallopingStrategy < T > . GallopLeft ( array , array [ baseA + lenA - 1 ] , baseB , lenB , comparer ) ;
484
377
485
378
if ( lenB <= 0 )
486
379
{
@@ -595,7 +488,7 @@ private bool StableMerge(TimChunk<T> left, TimChunk<T> right, ref int dest, int
595
488
596
489
private bool GallopMerge ( TimChunk < T > left , TimChunk < T > right , ref int dest )
597
490
{
598
- left . Wins = GallopRight ( left . Array , right . Array [ right . Index ] , left . Index , left . Remaining , 0 ) ;
491
+ left . Wins = GallopingStrategy < T > . GallopRight ( left . Array , right . Array [ right . Index ] , left . Index , left . Remaining , comparer ) ;
599
492
if ( left . Wins != 0 )
600
493
{
601
494
Array . Copy ( left . Array , left . Index , right . Array , dest , left . Wins ) ;
@@ -614,7 +507,7 @@ private bool GallopMerge(TimChunk<T> left, TimChunk<T> right, ref int dest)
614
507
return true ;
615
508
}
616
509
617
- right . Wins = GallopLeft ( right . Array , left . Array [ left . Index ] , right . Index , right . Remaining , 0 ) ;
510
+ right . Wins = GallopingStrategy < T > . GallopLeft ( right . Array , left . Array [ left . Index ] , right . Index , right . Remaining , comparer ) ;
618
511
if ( right . Wins != 0 )
619
512
{
620
513
Array . Copy ( right . Array , right . Index , right . Array , dest , right . Wins ) ;
0 commit comments