├── .classpath ├── .gitignore ├── .project ├── .settings └── org.eclipse.jdt.core.prefs └── src ├── Test ├── CountSortTest.java ├── DualPivotQuickSort.java └── RadixSortTest.java └── com └── mashibing ├── BinarySearch.java ├── BubbleSort.java ├── CountSort.java ├── DataChecker.java ├── InsertionSort.java ├── MergeSort.java ├── QuickSort.java ├── RadixSort.java ├── SelectionSort.java ├── ShellSort.java ├── TTT.java ├── T_0001_BigO.java ├── linkedlist ├── BiDirLL.java ├── BiDirLoopLL.java ├── Node.java ├── OneDirLoopLL.java └── SimpleLL.java └── search └── BinarySearch.java /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Algorithm 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled 3 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=10 4 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve 5 | org.eclipse.jdt.core.compiler.compliance=10 6 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate 7 | org.eclipse.jdt.core.compiler.debug.localVariable=generate 8 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate 9 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error 10 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error 11 | org.eclipse.jdt.core.compiler.source=10 12 | -------------------------------------------------------------------------------- /src/Test/CountSortTest.java: -------------------------------------------------------------------------------- 1 | package Test; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import java.util.Arrays; 6 | import java.util.Random; 7 | 8 | import org.junit.jupiter.api.Test; 9 | 10 | import com.mashibing.CountSort; 11 | 12 | class CountSortTest { 13 | 14 | int[] generateRandomArray() { 15 | Random r = new Random(); 16 | 17 | int[] arr = new int[10000]; 18 | 19 | for (int i = 0; i < arr.length; i++) 20 | arr[i] = r.nextInt(10); 21 | 22 | return arr; 23 | } 24 | 25 | 26 | @Test 27 | void testSort() { 28 | int[] a = generateRandomArray(); 29 | int[] result = CountSort.sort(a); 30 | Arrays.sort(a); 31 | boolean same = true; 32 | 33 | for (int i = 0; i < a.length; i++) { 34 | if(result[i] != a[i]) same = false; 35 | } 36 | 37 | assertEquals(true, same); 38 | 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/Test/DualPivotQuickSort.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. 3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 4 | * 5 | * 6 | * 7 | * 8 | * 9 | * 10 | * 11 | * 12 | * 13 | * 14 | * 15 | * 16 | * 17 | * 18 | * 19 | * 20 | * 21 | * 22 | * 23 | * 24 | */ 25 | 26 | package Test; 27 | 28 | /** 29 | * This class implements the Dual-Pivot Quicksort algorithm by 30 | * Vladimir Yaroslavskiy, Jon Bentley, and Josh Bloch. The algorithm 31 | * offers O(n log(n)) performance on many data sets that cause other 32 | * quicksorts to degrade to quadratic performance, and is typically 33 | * faster than traditional (one-pivot) Quicksort implementations. 34 | * 35 | * All exposed methods are package-private, designed to be invoked 36 | * from public methods (in class Arrays) after performing any 37 | * necessary array bounds checks and expanding parameters into the 38 | * required forms. 39 | * 40 | * @author Vladimir Yaroslavskiy 41 | * @author Jon Bentley 42 | * @author Josh Bloch 43 | * 44 | * @version 2011.02.11 m765.827.12i:5\7pm 45 | * @since 1.7 46 | */ 47 | final class DualPivotQuicksort { 48 | 49 | /** 50 | * Prevents instantiation. 51 | */ 52 | private DualPivotQuicksort() {} 53 | 54 | /* 55 | * Tuning parameters. 56 | */ 57 | 58 | /** 59 | * The maximum number of runs in merge sort. 60 | */ 61 | private static final int MAX_RUN_COUNT = 67; 62 | 63 | /** 64 | * If the length of an array to be sorted is less than this 65 | * constant, Quicksort is used in preference to merge sort. 66 | */ 67 | private static final int QUICKSORT_THRESHOLD = 286; 68 | 69 | /** 70 | * If the length of an array to be sorted is less than this 71 | * constant, insertion sort is used in preference to Quicksort. 72 | */ 73 | private static final int INSERTION_SORT_THRESHOLD = 47; 74 | 75 | /** 76 | * If the length of a byte array to be sorted is greater than this 77 | * constant, counting sort is used in preference to insertion sort. 78 | */ 79 | private static final int COUNTING_SORT_THRESHOLD_FOR_BYTE = 29; 80 | 81 | /** 82 | * If the length of a short or char array to be sorted is greater 83 | * than this constant, counting sort is used in preference to Quicksort. 84 | */ 85 | private static final int COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR = 3200; 86 | 87 | /* 88 | * Sorting methods for seven primitive types. 89 | */ 90 | 91 | /** 92 | * Sorts the specified range of the array using the given 93 | * workspace array slice if possible for merging 94 | * 95 | * @param a the array to be sorted 96 | * @param left the index of the first element, inclusive, to be sorted 97 | * @param right the index of the last element, inclusive, to be sorted 98 | * @param work a workspace array (slice) 99 | * @param workBase origin of usable space in work array 100 | * @param workLen usable size of work array 101 | */ 102 | static void sort(int[] a, int left, int right, 103 | int[] work, int workBase, int workLen) { 104 | // Use Quicksort on small arrays 105 | if (right - left < QUICKSORT_THRESHOLD) { 106 | sort(a, left, right, true); 107 | return; 108 | } 109 | 110 | /* 111 | * Index run[i] is the start of i-th run 112 | * (ascending or descending sequence). 113 | */ 114 | int[] run = new int[MAX_RUN_COUNT + 1]; 115 | int count = 0; run[0] = left; 116 | 117 | // Check if the array is nearly sorted 118 | for (int k = left; k < right; run[count] = k) { 119 | // Equal items in the beginning of the sequence 120 | while (k < right && a[k] == a[k + 1]) 121 | k++; 122 | if (k == right) break; // Sequence finishes with equal items 123 | if (a[k] < a[k + 1]) { // ascending 124 | while (++k <= right && a[k - 1] <= a[k]); 125 | } else if (a[k] > a[k + 1]) { // descending 126 | while (++k <= right && a[k - 1] >= a[k]); 127 | // Transform into an ascending sequence 128 | for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) { 129 | int t = a[lo]; a[lo] = a[hi]; a[hi] = t; 130 | } 131 | } 132 | 133 | // Merge a transformed descending sequence followed by an 134 | // ascending sequence 135 | if (run[count] > left && a[run[count]] >= a[run[count] - 1]) { 136 | count--; 137 | } 138 | 139 | /* 140 | * The array is not highly structured, 141 | * use Quicksort instead of merge sort. 142 | */ 143 | if (++count == MAX_RUN_COUNT) { 144 | sort(a, left, right, true); 145 | return; 146 | } 147 | } 148 | 149 | // These invariants should hold true: 150 | // run[0] = 0 151 | // run[] = right + 1; (terminator) 152 | 153 | if (count == 0) { 154 | // A single equal run 155 | return; 156 | } else if (count == 1 && run[count] > right) { 157 | // Either a single ascending or a transformed descending run. 158 | // Always check that a final run is a proper terminator, otherwise 159 | // we have an unterminated trailing run, to handle downstream. 160 | return; 161 | } 162 | right++; 163 | if (run[count] < right) { 164 | // Corner case: the final run is not a terminator. This may happen 165 | // if a final run is an equals run, or there is a single-element run 166 | // at the end. Fix up by adding a proper terminator at the end. 167 | // Note that we terminate with (right + 1), incremented earlier. 168 | run[++count] = right; 169 | } 170 | 171 | // Determine alternation base for merge 172 | byte odd = 0; 173 | for (int n = 1; (n <<= 1) < count; odd ^= 1); 174 | 175 | // Use or create temporary array b for merging 176 | int[] b; // temp array; alternates with a 177 | int ao, bo; // array offsets from 'left' 178 | int blen = right - left; // space needed for b 179 | if (work == null || workLen < blen || workBase + blen > work.length) { 180 | work = new int[blen]; 181 | workBase = 0; 182 | } 183 | if (odd == 0) { 184 | System.arraycopy(a, left, work, workBase, blen); 185 | b = a; 186 | bo = 0; 187 | a = work; 188 | ao = workBase - left; 189 | } else { 190 | b = work; 191 | ao = 0; 192 | bo = workBase - left; 193 | } 194 | 195 | // Merging 196 | for (int last; count > 1; count = last) { 197 | for (int k = (last = 0) + 2; k <= count; k += 2) { 198 | int hi = run[k], mi = run[k - 1]; 199 | for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) { 200 | if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) { 201 | b[i + bo] = a[p++ + ao]; 202 | } else { 203 | b[i + bo] = a[q++ + ao]; 204 | } 205 | } 206 | run[++last] = hi; 207 | } 208 | if ((count & 1) != 0) { 209 | for (int i = right, lo = run[count - 1]; --i >= lo; 210 | b[i + bo] = a[i + ao] 211 | ); 212 | run[++last] = right; 213 | } 214 | int[] t = a; a = b; b = t; 215 | int o = ao; ao = bo; bo = o; 216 | } 217 | } 218 | 219 | /** 220 | * Sorts the specified range of the array by Dual-Pivot Quicksort. 221 | * 222 | * @param a the array to be sorted 223 | * @param left the index of the first element, inclusive, to be sorted 224 | * @param right the index of the last element, inclusive, to be sorted 225 | * @param leftmost indicates if this part is the leftmost in the range 226 | */ 227 | private static void sort(int[] a, int left, int right, boolean leftmost) { 228 | int length = right - left + 1; 229 | 230 | // Use insertion sort on tiny arrays 231 | if (length < INSERTION_SORT_THRESHOLD) { 232 | if (leftmost) { 233 | /* 234 | * Traditional (without sentinel) insertion sort, 235 | * optimized for server VM, is used in case of 236 | * the leftmost part. 237 | */ 238 | for (int i = left, j = i; i < right; j = ++i) { 239 | int ai = a[i + 1]; 240 | while (ai < a[j]) { 241 | a[j + 1] = a[j]; 242 | if (j-- == left) { 243 | break; 244 | } 245 | } 246 | a[j + 1] = ai; 247 | } 248 | } else { 249 | /* 250 | * Skip the longest ascending sequence. 251 | */ 252 | do { 253 | if (left >= right) { 254 | return; 255 | } 256 | } while (a[++left] >= a[left - 1]); 257 | 258 | /* 259 | * Every element from adjoining part plays the role 260 | * of sentinel, therefore this allows us to avoid the 261 | * left range check on each iteration. Moreover, we use 262 | * the more optimized algorithm, so called pair insertion 263 | * sort, which is faster (in the context of Quicksort) 264 | * than traditional implementation of insertion sort. 265 | */ 266 | for (int k = left; ++left <= right; k = ++left) { 267 | int a1 = a[k], a2 = a[left]; 268 | 269 | if (a1 < a2) { 270 | a2 = a1; a1 = a[left]; 271 | } 272 | while (a1 < a[--k]) { 273 | a[k + 2] = a[k]; 274 | } 275 | a[++k + 1] = a1; 276 | 277 | while (a2 < a[--k]) { 278 | a[k + 1] = a[k]; 279 | } 280 | a[k + 1] = a2; 281 | } 282 | int last = a[right]; 283 | 284 | while (last < a[--right]) { 285 | a[right + 1] = a[right]; 286 | } 287 | a[right + 1] = last; 288 | } 289 | return; 290 | } 291 | 292 | // Inexpensive approximation of length / 7 293 | int seventh = (length >> 3) + (length >> 6) + 1; 294 | 295 | /* 296 | * Sort five evenly spaced elements around (and including) the 297 | * center element in the range. These elements will be used for 298 | * pivot selection as described below. The choice for spacing 299 | * these elements was empirically determined to work well on 300 | * a wide variety of inputs. 301 | */ 302 | int e3 = (left + right) >>> 1; // The midpoint 303 | int e2 = e3 - seventh; 304 | int e1 = e2 - seventh; 305 | int e4 = e3 + seventh; 306 | int e5 = e4 + seventh; 307 | 308 | // Sort these elements using insertion sort 309 | if (a[e2] < a[e1]) { int t = a[e2]; a[e2] = a[e1]; a[e1] = t; } 310 | 311 | if (a[e3] < a[e2]) { int t = a[e3]; a[e3] = a[e2]; a[e2] = t; 312 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 313 | } 314 | if (a[e4] < a[e3]) { int t = a[e4]; a[e4] = a[e3]; a[e3] = t; 315 | if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; 316 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 317 | } 318 | } 319 | if (a[e5] < a[e4]) { int t = a[e5]; a[e5] = a[e4]; a[e4] = t; 320 | if (t < a[e3]) { a[e4] = a[e3]; a[e3] = t; 321 | if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; 322 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 323 | } 324 | } 325 | } 326 | 327 | // Pointers 328 | int less = left; // The index of the first element of center part 329 | int great = right; // The index before the first element of right part 330 | 331 | if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) { 332 | /* 333 | * Use the second and fourth of the five sorted elements as pivots. 334 | * These values are inexpensive approximations of the first and 335 | * second terciles of the array. Note that pivot1 <= pivot2. 336 | */ 337 | int pivot1 = a[e2]; 338 | int pivot2 = a[e4]; 339 | 340 | /* 341 | * The first and the last elements to be sorted are moved to the 342 | * locations formerly occupied by the pivots. When partitioning 343 | * is complete, the pivots are swapped back into their final 344 | * positions, and excluded from subsequent sorting. 345 | */ 346 | a[e2] = a[left]; 347 | a[e4] = a[right]; 348 | 349 | /* 350 | * Skip elements, which are less or greater than pivot values. 351 | */ 352 | while (a[++less] < pivot1); 353 | while (a[--great] > pivot2); 354 | 355 | /* 356 | * Partitioning: 357 | * 358 | * left part center part right part 359 | * +--------------------------------------------------------------+ 360 | * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 | 361 | * +--------------------------------------------------------------+ 362 | * ^ ^ ^ 363 | * | | | 364 | * less k great 365 | * 366 | * Invariants: 367 | * 368 | * all in (left, less) < pivot1 369 | * pivot1 <= all in [less, k) <= pivot2 370 | * all in (great, right) > pivot2 371 | * 372 | * Pointer k is the first index of ?-part. 373 | */ 374 | outer: 375 | for (int k = less - 1; ++k <= great; ) { 376 | int ak = a[k]; 377 | if (ak < pivot1) { // Move a[k] to left part 378 | a[k] = a[less]; 379 | /* 380 | * Here and below we use "a[i] = b; i++;" instead 381 | * of "a[i++] = b;" due to performance issue. 382 | */ 383 | a[less] = ak; 384 | ++less; 385 | } else if (ak > pivot2) { // Move a[k] to right part 386 | while (a[great] > pivot2) { 387 | if (great-- == k) { 388 | break outer; 389 | } 390 | } 391 | if (a[great] < pivot1) { // a[great] <= pivot2 392 | a[k] = a[less]; 393 | a[less] = a[great]; 394 | ++less; 395 | } else { // pivot1 <= a[great] <= pivot2 396 | a[k] = a[great]; 397 | } 398 | /* 399 | * Here and below we use "a[i] = b; i--;" instead 400 | * of "a[i--] = b;" due to performance issue. 401 | */ 402 | a[great] = ak; 403 | --great; 404 | } 405 | } 406 | 407 | // Swap pivots into their final positions 408 | a[left] = a[less - 1]; a[less - 1] = pivot1; 409 | a[right] = a[great + 1]; a[great + 1] = pivot2; 410 | 411 | // Sort left and right parts recursively, excluding known pivots 412 | sort(a, left, less - 2, leftmost); 413 | sort(a, great + 2, right, false); 414 | 415 | /* 416 | * If center part is too large (comprises > 4/7 of the array), 417 | * swap internal pivot values to ends. 418 | */ 419 | if (less < e1 && e5 < great) { 420 | /* 421 | * Skip elements, which are equal to pivot values. 422 | */ 423 | while (a[less] == pivot1) { 424 | ++less; 425 | } 426 | 427 | while (a[great] == pivot2) { 428 | --great; 429 | } 430 | 431 | /* 432 | * Partitioning: 433 | * 434 | * left part center part right part 435 | * +----------------------------------------------------------+ 436 | * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 | 437 | * +----------------------------------------------------------+ 438 | * ^ ^ ^ 439 | * | | | 440 | * less k great 441 | * 442 | * Invariants: 443 | * 444 | * all in (*, less) == pivot1 445 | * pivot1 < all in [less, k) < pivot2 446 | * all in (great, *) == pivot2 447 | * 448 | * Pointer k is the first index of ?-part. 449 | */ 450 | outer: 451 | for (int k = less - 1; ++k <= great; ) { 452 | int ak = a[k]; 453 | if (ak == pivot1) { // Move a[k] to left part 454 | a[k] = a[less]; 455 | a[less] = ak; 456 | ++less; 457 | } else if (ak == pivot2) { // Move a[k] to right part 458 | while (a[great] == pivot2) { 459 | if (great-- == k) { 460 | break outer; 461 | } 462 | } 463 | if (a[great] == pivot1) { // a[great] < pivot2 464 | a[k] = a[less]; 465 | /* 466 | * Even though a[great] equals to pivot1, the 467 | * assignment a[less] = pivot1 may be incorrect, 468 | * if a[great] and pivot1 are floating-point zeros 469 | * of different signs. Therefore in float and 470 | * double sorting methods we have to use more 471 | * accurate assignment a[less] = a[great]. 472 | */ 473 | a[less] = pivot1; 474 | ++less; 475 | } else { // pivot1 < a[great] < pivot2 476 | a[k] = a[great]; 477 | } 478 | a[great] = ak; 479 | --great; 480 | } 481 | } 482 | } 483 | 484 | // Sort center part recursively 485 | sort(a, less, great, false); 486 | 487 | } else { // Partitioning with one pivot 488 | /* 489 | * Use the third of the five sorted elements as pivot. 490 | * This value is inexpensive approximation of the median. 491 | */ 492 | int pivot = a[e3]; 493 | 494 | /* 495 | * Partitioning degenerates to the traditional 3-way 496 | * (or "Dutch National Flag") schema: 497 | * 498 | * left part center part right part 499 | * +-------------------------------------------------+ 500 | * | < pivot | == pivot | ? | > pivot | 501 | * +-------------------------------------------------+ 502 | * ^ ^ ^ 503 | * | | | 504 | * less k great 505 | * 506 | * Invariants: 507 | * 508 | * all in (left, less) < pivot 509 | * all in [less, k) == pivot 510 | * all in (great, right) > pivot 511 | * 512 | * Pointer k is the first index of ?-part. 513 | */ 514 | for (int k = less; k <= great; ++k) { 515 | if (a[k] == pivot) { 516 | continue; 517 | } 518 | int ak = a[k]; 519 | if (ak < pivot) { // Move a[k] to left part 520 | a[k] = a[less]; 521 | a[less] = ak; 522 | ++less; 523 | } else { // a[k] > pivot - Move a[k] to right part 524 | while (a[great] > pivot) { 525 | --great; 526 | } 527 | if (a[great] < pivot) { // a[great] <= pivot 528 | a[k] = a[less]; 529 | a[less] = a[great]; 530 | ++less; 531 | } else { // a[great] == pivot 532 | /* 533 | * Even though a[great] equals to pivot, the 534 | * assignment a[k] = pivot may be incorrect, 535 | * if a[great] and pivot are floating-point 536 | * zeros of different signs. Therefore in float 537 | * and double sorting methods we have to use 538 | * more accurate assignment a[k] = a[great]. 539 | */ 540 | a[k] = pivot; 541 | } 542 | a[great] = ak; 543 | --great; 544 | } 545 | } 546 | 547 | /* 548 | * Sort left and right parts recursively. 549 | * All elements from center part are equal 550 | * and, therefore, already sorted. 551 | */ 552 | sort(a, left, less - 1, leftmost); 553 | sort(a, great + 1, right, false); 554 | } 555 | } 556 | 557 | /** 558 | * Sorts the specified range of the array using the given 559 | * workspace array slice if possible for merging 560 | * 561 | * @param a the array to be sorted 562 | * @param left the index of the first element, inclusive, to be sorted 563 | * @param right the index of the last element, inclusive, to be sorted 564 | * @param work a workspace array (slice) 565 | * @param workBase origin of usable space in work array 566 | * @param workLen usable size of work array 567 | */ 568 | static void sort(long[] a, int left, int right, 569 | long[] work, int workBase, int workLen) { 570 | // Use Quicksort on small arrays 571 | if (right - left < QUICKSORT_THRESHOLD) { 572 | sort(a, left, right, true); 573 | return; 574 | } 575 | 576 | /* 577 | * Index run[i] is the start of i-th run 578 | * (ascending or descending sequence). 579 | */ 580 | int[] run = new int[MAX_RUN_COUNT + 1]; 581 | int count = 0; run[0] = left; 582 | 583 | // Check if the array is nearly sorted 584 | for (int k = left; k < right; run[count] = k) { 585 | // Equal items in the beginning of the sequence 586 | while (k < right && a[k] == a[k + 1]) 587 | k++; 588 | if (k == right) break; // Sequence finishes with equal items 589 | if (a[k] < a[k + 1]) { // ascending 590 | while (++k <= right && a[k - 1] <= a[k]); 591 | } else if (a[k] > a[k + 1]) { // descending 592 | while (++k <= right && a[k - 1] >= a[k]); 593 | // Transform into an ascending sequence 594 | for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) { 595 | long t = a[lo]; a[lo] = a[hi]; a[hi] = t; 596 | } 597 | } 598 | 599 | // Merge a transformed descending sequence followed by an 600 | // ascending sequence 601 | if (run[count] > left && a[run[count]] >= a[run[count] - 1]) { 602 | count--; 603 | } 604 | 605 | /* 606 | * The array is not highly structured, 607 | * use Quicksort instead of merge sort. 608 | */ 609 | if (++count == MAX_RUN_COUNT) { 610 | sort(a, left, right, true); 611 | return; 612 | } 613 | } 614 | 615 | // These invariants should hold true: 616 | // run[0] = 0 617 | // run[] = right + 1; (terminator) 618 | 619 | if (count == 0) { 620 | // A single equal run 621 | return; 622 | } else if (count == 1 && run[count] > right) { 623 | // Either a single ascending or a transformed descending run. 624 | // Always check that a final run is a proper terminator, otherwise 625 | // we have an unterminated trailing run, to handle downstream. 626 | return; 627 | } 628 | right++; 629 | if (run[count] < right) { 630 | // Corner case: the final run is not a terminator. This may happen 631 | // if a final run is an equals run, or there is a single-element run 632 | // at the end. Fix up by adding a proper terminator at the end. 633 | // Note that we terminate with (right + 1), incremented earlier. 634 | run[++count] = right; 635 | } 636 | 637 | // Determine alternation base for merge 638 | byte odd = 0; 639 | for (int n = 1; (n <<= 1) < count; odd ^= 1); 640 | 641 | // Use or create temporary array b for merging 642 | long[] b; // temp array; alternates with a 643 | int ao, bo; // array offsets from 'left' 644 | int blen = right - left; // space needed for b 645 | if (work == null || workLen < blen || workBase + blen > work.length) { 646 | work = new long[blen]; 647 | workBase = 0; 648 | } 649 | if (odd == 0) { 650 | System.arraycopy(a, left, work, workBase, blen); 651 | b = a; 652 | bo = 0; 653 | a = work; 654 | ao = workBase - left; 655 | } else { 656 | b = work; 657 | ao = 0; 658 | bo = workBase - left; 659 | } 660 | 661 | // Merging 662 | for (int last; count > 1; count = last) { 663 | for (int k = (last = 0) + 2; k <= count; k += 2) { 664 | int hi = run[k], mi = run[k - 1]; 665 | for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) { 666 | if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) { 667 | b[i + bo] = a[p++ + ao]; 668 | } else { 669 | b[i + bo] = a[q++ + ao]; 670 | } 671 | } 672 | run[++last] = hi; 673 | } 674 | if ((count & 1) != 0) { 675 | for (int i = right, lo = run[count - 1]; --i >= lo; 676 | b[i + bo] = a[i + ao] 677 | ); 678 | run[++last] = right; 679 | } 680 | long[] t = a; a = b; b = t; 681 | int o = ao; ao = bo; bo = o; 682 | } 683 | } 684 | 685 | /** 686 | * Sorts the specified range of the array by Dual-Pivot Quicksort. 687 | * 688 | * @param a the array to be sorted 689 | * @param left the index of the first element, inclusive, to be sorted 690 | * @param right the index of the last element, inclusive, to be sorted 691 | * @param leftmost indicates if this part is the leftmost in the range 692 | */ 693 | private static void sort(long[] a, int left, int right, boolean leftmost) { 694 | int length = right - left + 1; 695 | 696 | // Use insertion sort on tiny arrays 697 | if (length < INSERTION_SORT_THRESHOLD) { 698 | if (leftmost) { 699 | /* 700 | * Traditional (without sentinel) insertion sort, 701 | * optimized for server VM, is used in case of 702 | * the leftmost part. 703 | */ 704 | for (int i = left, j = i; i < right; j = ++i) { 705 | long ai = a[i + 1]; 706 | while (ai < a[j]) { 707 | a[j + 1] = a[j]; 708 | if (j-- == left) { 709 | break; 710 | } 711 | } 712 | a[j + 1] = ai; 713 | } 714 | } else { 715 | /* 716 | * Skip the longest ascending sequence. 717 | */ 718 | do { 719 | if (left >= right) { 720 | return; 721 | } 722 | } while (a[++left] >= a[left - 1]); 723 | 724 | /* 725 | * Every element from adjoining part plays the role 726 | * of sentinel, therefore this allows us to avoid the 727 | * left range check on each iteration. Moreover, we use 728 | * the more optimized algorithm, so called pair insertion 729 | * sort, which is faster (in the context of Quicksort) 730 | * than traditional implementation of insertion sort. 731 | */ 732 | for (int k = left; ++left <= right; k = ++left) { 733 | long a1 = a[k], a2 = a[left]; 734 | 735 | if (a1 < a2) { 736 | a2 = a1; a1 = a[left]; 737 | } 738 | while (a1 < a[--k]) { 739 | a[k + 2] = a[k]; 740 | } 741 | a[++k + 1] = a1; 742 | 743 | while (a2 < a[--k]) { 744 | a[k + 1] = a[k]; 745 | } 746 | a[k + 1] = a2; 747 | } 748 | long last = a[right]; 749 | 750 | while (last < a[--right]) { 751 | a[right + 1] = a[right]; 752 | } 753 | a[right + 1] = last; 754 | } 755 | return; 756 | } 757 | 758 | // Inexpensive approximation of length / 7 759 | int seventh = (length >> 3) + (length >> 6) + 1; 760 | 761 | /* 762 | * Sort five evenly spaced elements around (and including) the 763 | * center element in the range. These elements will be used for 764 | * pivot selection as described below. The choice for spacing 765 | * these elements was empirically determined to work well on 766 | * a wide variety of inputs. 767 | */ 768 | int e3 = (left + right) >>> 1; // The midpoint 769 | int e2 = e3 - seventh; 770 | int e1 = e2 - seventh; 771 | int e4 = e3 + seventh; 772 | int e5 = e4 + seventh; 773 | 774 | // Sort these elements using insertion sort 775 | if (a[e2] < a[e1]) { long t = a[e2]; a[e2] = a[e1]; a[e1] = t; } 776 | 777 | if (a[e3] < a[e2]) { long t = a[e3]; a[e3] = a[e2]; a[e2] = t; 778 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 779 | } 780 | if (a[e4] < a[e3]) { long t = a[e4]; a[e4] = a[e3]; a[e3] = t; 781 | if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; 782 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 783 | } 784 | } 785 | if (a[e5] < a[e4]) { long t = a[e5]; a[e5] = a[e4]; a[e4] = t; 786 | if (t < a[e3]) { a[e4] = a[e3]; a[e3] = t; 787 | if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; 788 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 789 | } 790 | } 791 | } 792 | 793 | // Pointers 794 | int less = left; // The index of the first element of center part 795 | int great = right; // The index before the first element of right part 796 | 797 | if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) { 798 | /* 799 | * Use the second and fourth of the five sorted elements as pivots. 800 | * These values are inexpensive approximations of the first and 801 | * second terciles of the array. Note that pivot1 <= pivot2. 802 | */ 803 | long pivot1 = a[e2]; 804 | long pivot2 = a[e4]; 805 | 806 | /* 807 | * The first and the last elements to be sorted are moved to the 808 | * locations formerly occupied by the pivots. When partitioning 809 | * is complete, the pivots are swapped back into their final 810 | * positions, and excluded from subsequent sorting. 811 | */ 812 | a[e2] = a[left]; 813 | a[e4] = a[right]; 814 | 815 | /* 816 | * Skip elements, which are less or greater than pivot values. 817 | */ 818 | while (a[++less] < pivot1); 819 | while (a[--great] > pivot2); 820 | 821 | /* 822 | * Partitioning: 823 | * 824 | * left part center part right part 825 | * +--------------------------------------------------------------+ 826 | * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 | 827 | * +--------------------------------------------------------------+ 828 | * ^ ^ ^ 829 | * | | | 830 | * less k great 831 | * 832 | * Invariants: 833 | * 834 | * all in (left, less) < pivot1 835 | * pivot1 <= all in [less, k) <= pivot2 836 | * all in (great, right) > pivot2 837 | * 838 | * Pointer k is the first index of ?-part. 839 | */ 840 | outer: 841 | for (int k = less - 1; ++k <= great; ) { 842 | long ak = a[k]; 843 | if (ak < pivot1) { // Move a[k] to left part 844 | a[k] = a[less]; 845 | /* 846 | * Here and below we use "a[i] = b; i++;" instead 847 | * of "a[i++] = b;" due to performance issue. 848 | */ 849 | a[less] = ak; 850 | ++less; 851 | } else if (ak > pivot2) { // Move a[k] to right part 852 | while (a[great] > pivot2) { 853 | if (great-- == k) { 854 | break outer; 855 | } 856 | } 857 | if (a[great] < pivot1) { // a[great] <= pivot2 858 | a[k] = a[less]; 859 | a[less] = a[great]; 860 | ++less; 861 | } else { // pivot1 <= a[great] <= pivot2 862 | a[k] = a[great]; 863 | } 864 | /* 865 | * Here and below we use "a[i] = b; i--;" instead 866 | * of "a[i--] = b;" due to performance issue. 867 | */ 868 | a[great] = ak; 869 | --great; 870 | } 871 | } 872 | 873 | // Swap pivots into their final positions 874 | a[left] = a[less - 1]; a[less - 1] = pivot1; 875 | a[right] = a[great + 1]; a[great + 1] = pivot2; 876 | 877 | // Sort left and right parts recursively, excluding known pivots 878 | sort(a, left, less - 2, leftmost); 879 | sort(a, great + 2, right, false); 880 | 881 | /* 882 | * If center part is too large (comprises > 4/7 of the array), 883 | * swap internal pivot values to ends. 884 | */ 885 | if (less < e1 && e5 < great) { 886 | /* 887 | * Skip elements, which are equal to pivot values. 888 | */ 889 | while (a[less] == pivot1) { 890 | ++less; 891 | } 892 | 893 | while (a[great] == pivot2) { 894 | --great; 895 | } 896 | 897 | /* 898 | * Partitioning: 899 | * 900 | * left part center part right part 901 | * +----------------------------------------------------------+ 902 | * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 | 903 | * +----------------------------------------------------------+ 904 | * ^ ^ ^ 905 | * | | | 906 | * less k great 907 | * 908 | * Invariants: 909 | * 910 | * all in (*, less) == pivot1 911 | * pivot1 < all in [less, k) < pivot2 912 | * all in (great, *) == pivot2 913 | * 914 | * Pointer k is the first index of ?-part. 915 | */ 916 | outer: 917 | for (int k = less - 1; ++k <= great; ) { 918 | long ak = a[k]; 919 | if (ak == pivot1) { // Move a[k] to left part 920 | a[k] = a[less]; 921 | a[less] = ak; 922 | ++less; 923 | } else if (ak == pivot2) { // Move a[k] to right part 924 | while (a[great] == pivot2) { 925 | if (great-- == k) { 926 | break outer; 927 | } 928 | } 929 | if (a[great] == pivot1) { // a[great] < pivot2 930 | a[k] = a[less]; 931 | /* 932 | * Even though a[great] equals to pivot1, the 933 | * assignment a[less] = pivot1 may be incorrect, 934 | * if a[great] and pivot1 are floating-point zeros 935 | * of different signs. Therefore in float and 936 | * double sorting methods we have to use more 937 | * accurate assignment a[less] = a[great]. 938 | */ 939 | a[less] = pivot1; 940 | ++less; 941 | } else { // pivot1 < a[great] < pivot2 942 | a[k] = a[great]; 943 | } 944 | a[great] = ak; 945 | --great; 946 | } 947 | } 948 | } 949 | 950 | // Sort center part recursively 951 | sort(a, less, great, false); 952 | 953 | } else { // Partitioning with one pivot 954 | /* 955 | * Use the third of the five sorted elements as pivot. 956 | * This value is inexpensive approximation of the median. 957 | */ 958 | long pivot = a[e3]; 959 | 960 | /* 961 | * Partitioning degenerates to the traditional 3-way 962 | * (or "Dutch National Flag") schema: 963 | * 964 | * left part center part right part 965 | * +-------------------------------------------------+ 966 | * | < pivot | == pivot | ? | > pivot | 967 | * +-------------------------------------------------+ 968 | * ^ ^ ^ 969 | * | | | 970 | * less k great 971 | * 972 | * Invariants: 973 | * 974 | * all in (left, less) < pivot 975 | * all in [less, k) == pivot 976 | * all in (great, right) > pivot 977 | * 978 | * Pointer k is the first index of ?-part. 979 | */ 980 | for (int k = less; k <= great; ++k) { 981 | if (a[k] == pivot) { 982 | continue; 983 | } 984 | long ak = a[k]; 985 | if (ak < pivot) { // Move a[k] to left part 986 | a[k] = a[less]; 987 | a[less] = ak; 988 | ++less; 989 | } else { // a[k] > pivot - Move a[k] to right part 990 | while (a[great] > pivot) { 991 | --great; 992 | } 993 | if (a[great] < pivot) { // a[great] <= pivot 994 | a[k] = a[less]; 995 | a[less] = a[great]; 996 | ++less; 997 | } else { // a[great] == pivot 998 | /* 999 | * Even though a[great] equals to pivot, the 1000 | * assignment a[k] = pivot may be incorrect, 1001 | * if a[great] and pivot are floating-point 1002 | * zeros of different signs. Therefore in float 1003 | * and double sorting methods we have to use 1004 | * more accurate assignment a[k] = a[great]. 1005 | */ 1006 | a[k] = pivot; 1007 | } 1008 | a[great] = ak; 1009 | --great; 1010 | } 1011 | } 1012 | 1013 | /* 1014 | * Sort left and right parts recursively. 1015 | * All elements from center part are equal 1016 | * and, therefore, already sorted. 1017 | */ 1018 | sort(a, left, less - 1, leftmost); 1019 | sort(a, great + 1, right, false); 1020 | } 1021 | } 1022 | 1023 | /** 1024 | * Sorts the specified range of the array using the given 1025 | * workspace array slice if possible for merging 1026 | * 1027 | * @param a the array to be sorted 1028 | * @param left the index of the first element, inclusive, to be sorted 1029 | * @param right the index of the last element, inclusive, to be sorted 1030 | * @param work a workspace array (slice) 1031 | * @param workBase origin of usable space in work array 1032 | * @param workLen usable size of work array 1033 | */ 1034 | static void sort(short[] a, int left, int right, 1035 | short[] work, int workBase, int workLen) { 1036 | // Use counting sort on large arrays 1037 | if (right - left > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { 1038 | int[] count = new int[NUM_SHORT_VALUES]; 1039 | 1040 | for (int i = left - 1; ++i <= right; 1041 | count[a[i] - Short.MIN_VALUE]++ 1042 | ); 1043 | for (int i = NUM_SHORT_VALUES, k = right + 1; k > left; ) { 1044 | while (count[--i] == 0); 1045 | short value = (short) (i + Short.MIN_VALUE); 1046 | int s = count[i]; 1047 | 1048 | do { 1049 | a[--k] = value; 1050 | } while (--s > 0); 1051 | } 1052 | } else { // Use Dual-Pivot Quicksort on small arrays 1053 | doSort(a, left, right, work, workBase, workLen); 1054 | } 1055 | } 1056 | 1057 | /** The number of distinct short values. */ 1058 | private static final int NUM_SHORT_VALUES = 1 << 16; 1059 | 1060 | /** 1061 | * Sorts the specified range of the array. 1062 | * 1063 | * @param a the array to be sorted 1064 | * @param left the index of the first element, inclusive, to be sorted 1065 | * @param right the index of the last element, inclusive, to be sorted 1066 | * @param work a workspace array (slice) 1067 | * @param workBase origin of usable space in work array 1068 | * @param workLen usable size of work array 1069 | */ 1070 | private static void doSort(short[] a, int left, int right, 1071 | short[] work, int workBase, int workLen) { 1072 | // Use Quicksort on small arrays 1073 | if (right - left < QUICKSORT_THRESHOLD) { 1074 | sort(a, left, right, true); 1075 | return; 1076 | } 1077 | 1078 | /* 1079 | * Index run[i] is the start of i-th run 1080 | * (ascending or descending sequence). 1081 | */ 1082 | int[] run = new int[MAX_RUN_COUNT + 1]; 1083 | int count = 0; run[0] = left; 1084 | 1085 | // Check if the array is nearly sorted 1086 | for (int k = left; k < right; run[count] = k) { 1087 | // Equal items in the beginning of the sequence 1088 | while (k < right && a[k] == a[k + 1]) 1089 | k++; 1090 | if (k == right) break; // Sequence finishes with equal items 1091 | if (a[k] < a[k + 1]) { // ascending 1092 | while (++k <= right && a[k - 1] <= a[k]); 1093 | } else if (a[k] > a[k + 1]) { // descending 1094 | while (++k <= right && a[k - 1] >= a[k]); 1095 | // Transform into an ascending sequence 1096 | for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) { 1097 | short t = a[lo]; a[lo] = a[hi]; a[hi] = t; 1098 | } 1099 | } 1100 | 1101 | // Merge a transformed descending sequence followed by an 1102 | // ascending sequence 1103 | if (run[count] > left && a[run[count]] >= a[run[count] - 1]) { 1104 | count--; 1105 | } 1106 | 1107 | /* 1108 | * The array is not highly structured, 1109 | * use Quicksort instead of merge sort. 1110 | */ 1111 | if (++count == MAX_RUN_COUNT) { 1112 | sort(a, left, right, true); 1113 | return; 1114 | } 1115 | } 1116 | 1117 | // These invariants should hold true: 1118 | // run[0] = 0 1119 | // run[] = right + 1; (terminator) 1120 | 1121 | if (count == 0) { 1122 | // A single equal run 1123 | return; 1124 | } else if (count == 1 && run[count] > right) { 1125 | // Either a single ascending or a transformed descending run. 1126 | // Always check that a final run is a proper terminator, otherwise 1127 | // we have an unterminated trailing run, to handle downstream. 1128 | return; 1129 | } 1130 | right++; 1131 | if (run[count] < right) { 1132 | // Corner case: the final run is not a terminator. This may happen 1133 | // if a final run is an equals run, or there is a single-element run 1134 | // at the end. Fix up by adding a proper terminator at the end. 1135 | // Note that we terminate with (right + 1), incremented earlier. 1136 | run[++count] = right; 1137 | } 1138 | 1139 | // Determine alternation base for merge 1140 | byte odd = 0; 1141 | for (int n = 1; (n <<= 1) < count; odd ^= 1); 1142 | 1143 | // Use or create temporary array b for merging 1144 | short[] b; // temp array; alternates with a 1145 | int ao, bo; // array offsets from 'left' 1146 | int blen = right - left; // space needed for b 1147 | if (work == null || workLen < blen || workBase + blen > work.length) { 1148 | work = new short[blen]; 1149 | workBase = 0; 1150 | } 1151 | if (odd == 0) { 1152 | System.arraycopy(a, left, work, workBase, blen); 1153 | b = a; 1154 | bo = 0; 1155 | a = work; 1156 | ao = workBase - left; 1157 | } else { 1158 | b = work; 1159 | ao = 0; 1160 | bo = workBase - left; 1161 | } 1162 | 1163 | // Merging 1164 | for (int last; count > 1; count = last) { 1165 | for (int k = (last = 0) + 2; k <= count; k += 2) { 1166 | int hi = run[k], mi = run[k - 1]; 1167 | for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) { 1168 | if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) { 1169 | b[i + bo] = a[p++ + ao]; 1170 | } else { 1171 | b[i + bo] = a[q++ + ao]; 1172 | } 1173 | } 1174 | run[++last] = hi; 1175 | } 1176 | if ((count & 1) != 0) { 1177 | for (int i = right, lo = run[count - 1]; --i >= lo; 1178 | b[i + bo] = a[i + ao] 1179 | ); 1180 | run[++last] = right; 1181 | } 1182 | short[] t = a; a = b; b = t; 1183 | int o = ao; ao = bo; bo = o; 1184 | } 1185 | } 1186 | 1187 | /** 1188 | * Sorts the specified range of the array by Dual-Pivot Quicksort. 1189 | * 1190 | * @param a the array to be sorted 1191 | * @param left the index of the first element, inclusive, to be sorted 1192 | * @param right the index of the last element, inclusive, to be sorted 1193 | * @param leftmost indicates if this part is the leftmost in the range 1194 | */ 1195 | private static void sort(short[] a, int left, int right, boolean leftmost) { 1196 | int length = right - left + 1; 1197 | 1198 | // Use insertion sort on tiny arrays 1199 | if (length < INSERTION_SORT_THRESHOLD) { 1200 | if (leftmost) { 1201 | /* 1202 | * Traditional (without sentinel) insertion sort, 1203 | * optimized for server VM, is used in case of 1204 | * the leftmost part. 1205 | */ 1206 | for (int i = left, j = i; i < right; j = ++i) { 1207 | short ai = a[i + 1]; 1208 | while (ai < a[j]) { 1209 | a[j + 1] = a[j]; 1210 | if (j-- == left) { 1211 | break; 1212 | } 1213 | } 1214 | a[j + 1] = ai; 1215 | } 1216 | } else { 1217 | /* 1218 | * Skip the longest ascending sequence. 1219 | */ 1220 | do { 1221 | if (left >= right) { 1222 | return; 1223 | } 1224 | } while (a[++left] >= a[left - 1]); 1225 | 1226 | /* 1227 | * Every element from adjoining part plays the role 1228 | * of sentinel, therefore this allows us to avoid the 1229 | * left range check on each iteration. Moreover, we use 1230 | * the more optimized algorithm, so called pair insertion 1231 | * sort, which is faster (in the context of Quicksort) 1232 | * than traditional implementation of insertion sort. 1233 | */ 1234 | for (int k = left; ++left <= right; k = ++left) { 1235 | short a1 = a[k], a2 = a[left]; 1236 | 1237 | if (a1 < a2) { 1238 | a2 = a1; a1 = a[left]; 1239 | } 1240 | while (a1 < a[--k]) { 1241 | a[k + 2] = a[k]; 1242 | } 1243 | a[++k + 1] = a1; 1244 | 1245 | while (a2 < a[--k]) { 1246 | a[k + 1] = a[k]; 1247 | } 1248 | a[k + 1] = a2; 1249 | } 1250 | short last = a[right]; 1251 | 1252 | while (last < a[--right]) { 1253 | a[right + 1] = a[right]; 1254 | } 1255 | a[right + 1] = last; 1256 | } 1257 | return; 1258 | } 1259 | 1260 | // Inexpensive approximation of length / 7 1261 | int seventh = (length >> 3) + (length >> 6) + 1; 1262 | 1263 | /* 1264 | * Sort five evenly spaced elements around (and including) the 1265 | * center element in the range. These elements will be used for 1266 | * pivot selection as described below. The choice for spacing 1267 | * these elements was empirically determined to work well on 1268 | * a wide variety of inputs. 1269 | */ 1270 | int e3 = (left + right) >>> 1; // The midpoint 1271 | int e2 = e3 - seventh; 1272 | int e1 = e2 - seventh; 1273 | int e4 = e3 + seventh; 1274 | int e5 = e4 + seventh; 1275 | 1276 | // Sort these elements using insertion sort 1277 | if (a[e2] < a[e1]) { short t = a[e2]; a[e2] = a[e1]; a[e1] = t; } 1278 | 1279 | if (a[e3] < a[e2]) { short t = a[e3]; a[e3] = a[e2]; a[e2] = t; 1280 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 1281 | } 1282 | if (a[e4] < a[e3]) { short t = a[e4]; a[e4] = a[e3]; a[e3] = t; 1283 | if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; 1284 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 1285 | } 1286 | } 1287 | if (a[e5] < a[e4]) { short t = a[e5]; a[e5] = a[e4]; a[e4] = t; 1288 | if (t < a[e3]) { a[e4] = a[e3]; a[e3] = t; 1289 | if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; 1290 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 1291 | } 1292 | } 1293 | } 1294 | 1295 | // Pointers 1296 | int less = left; // The index of the first element of center part 1297 | int great = right; // The index before the first element of right part 1298 | 1299 | if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) { 1300 | /* 1301 | * Use the second and fourth of the five sorted elements as pivots. 1302 | * These values are inexpensive approximations of the first and 1303 | * second terciles of the array. Note that pivot1 <= pivot2. 1304 | */ 1305 | short pivot1 = a[e2]; 1306 | short pivot2 = a[e4]; 1307 | 1308 | /* 1309 | * The first and the last elements to be sorted are moved to the 1310 | * locations formerly occupied by the pivots. When partitioning 1311 | * is complete, the pivots are swapped back into their final 1312 | * positions, and excluded from subsequent sorting. 1313 | */ 1314 | a[e2] = a[left]; 1315 | a[e4] = a[right]; 1316 | 1317 | /* 1318 | * Skip elements, which are less or greater than pivot values. 1319 | */ 1320 | while (a[++less] < pivot1); 1321 | while (a[--great] > pivot2); 1322 | 1323 | /* 1324 | * Partitioning: 1325 | * 1326 | * left part center part right part 1327 | * +--------------------------------------------------------------+ 1328 | * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 | 1329 | * +--------------------------------------------------------------+ 1330 | * ^ ^ ^ 1331 | * | | | 1332 | * less k great 1333 | * 1334 | * Invariants: 1335 | * 1336 | * all in (left, less) < pivot1 1337 | * pivot1 <= all in [less, k) <= pivot2 1338 | * all in (great, right) > pivot2 1339 | * 1340 | * Pointer k is the first index of ?-part. 1341 | */ 1342 | outer: 1343 | for (int k = less - 1; ++k <= great; ) { 1344 | short ak = a[k]; 1345 | if (ak < pivot1) { // Move a[k] to left part 1346 | a[k] = a[less]; 1347 | /* 1348 | * Here and below we use "a[i] = b; i++;" instead 1349 | * of "a[i++] = b;" due to performance issue. 1350 | */ 1351 | a[less] = ak; 1352 | ++less; 1353 | } else if (ak > pivot2) { // Move a[k] to right part 1354 | while (a[great] > pivot2) { 1355 | if (great-- == k) { 1356 | break outer; 1357 | } 1358 | } 1359 | if (a[great] < pivot1) { // a[great] <= pivot2 1360 | a[k] = a[less]; 1361 | a[less] = a[great]; 1362 | ++less; 1363 | } else { // pivot1 <= a[great] <= pivot2 1364 | a[k] = a[great]; 1365 | } 1366 | /* 1367 | * Here and below we use "a[i] = b; i--;" instead 1368 | * of "a[i--] = b;" due to performance issue. 1369 | */ 1370 | a[great] = ak; 1371 | --great; 1372 | } 1373 | } 1374 | 1375 | // Swap pivots into their final positions 1376 | a[left] = a[less - 1]; a[less - 1] = pivot1; 1377 | a[right] = a[great + 1]; a[great + 1] = pivot2; 1378 | 1379 | // Sort left and right parts recursively, excluding known pivots 1380 | sort(a, left, less - 2, leftmost); 1381 | sort(a, great + 2, right, false); 1382 | 1383 | /* 1384 | * If center part is too large (comprises > 4/7 of the array), 1385 | * swap internal pivot values to ends. 1386 | */ 1387 | if (less < e1 && e5 < great) { 1388 | /* 1389 | * Skip elements, which are equal to pivot values. 1390 | */ 1391 | while (a[less] == pivot1) { 1392 | ++less; 1393 | } 1394 | 1395 | while (a[great] == pivot2) { 1396 | --great; 1397 | } 1398 | 1399 | /* 1400 | * Partitioning: 1401 | * 1402 | * left part center part right part 1403 | * +----------------------------------------------------------+ 1404 | * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 | 1405 | * +----------------------------------------------------------+ 1406 | * ^ ^ ^ 1407 | * | | | 1408 | * less k great 1409 | * 1410 | * Invariants: 1411 | * 1412 | * all in (*, less) == pivot1 1413 | * pivot1 < all in [less, k) < pivot2 1414 | * all in (great, *) == pivot2 1415 | * 1416 | * Pointer k is the first index of ?-part. 1417 | */ 1418 | outer: 1419 | for (int k = less - 1; ++k <= great; ) { 1420 | short ak = a[k]; 1421 | if (ak == pivot1) { // Move a[k] to left part 1422 | a[k] = a[less]; 1423 | a[less] = ak; 1424 | ++less; 1425 | } else if (ak == pivot2) { // Move a[k] to right part 1426 | while (a[great] == pivot2) { 1427 | if (great-- == k) { 1428 | break outer; 1429 | } 1430 | } 1431 | if (a[great] == pivot1) { // a[great] < pivot2 1432 | a[k] = a[less]; 1433 | /* 1434 | * Even though a[great] equals to pivot1, the 1435 | * assignment a[less] = pivot1 may be incorrect, 1436 | * if a[great] and pivot1 are floating-point zeros 1437 | * of different signs. Therefore in float and 1438 | * double sorting methods we have to use more 1439 | * accurate assignment a[less] = a[great]. 1440 | */ 1441 | a[less] = pivot1; 1442 | ++less; 1443 | } else { // pivot1 < a[great] < pivot2 1444 | a[k] = a[great]; 1445 | } 1446 | a[great] = ak; 1447 | --great; 1448 | } 1449 | } 1450 | } 1451 | 1452 | // Sort center part recursively 1453 | sort(a, less, great, false); 1454 | 1455 | } else { // Partitioning with one pivot 1456 | /* 1457 | * Use the third of the five sorted elements as pivot. 1458 | * This value is inexpensive approximation of the median. 1459 | */ 1460 | short pivot = a[e3]; 1461 | 1462 | /* 1463 | * Partitioning degenerates to the traditional 3-way 1464 | * (or "Dutch National Flag") schema: 1465 | * 1466 | * left part center part right part 1467 | * +-------------------------------------------------+ 1468 | * | < pivot | == pivot | ? | > pivot | 1469 | * +-------------------------------------------------+ 1470 | * ^ ^ ^ 1471 | * | | | 1472 | * less k great 1473 | * 1474 | * Invariants: 1475 | * 1476 | * all in (left, less) < pivot 1477 | * all in [less, k) == pivot 1478 | * all in (great, right) > pivot 1479 | * 1480 | * Pointer k is the first index of ?-part. 1481 | */ 1482 | for (int k = less; k <= great; ++k) { 1483 | if (a[k] == pivot) { 1484 | continue; 1485 | } 1486 | short ak = a[k]; 1487 | if (ak < pivot) { // Move a[k] to left part 1488 | a[k] = a[less]; 1489 | a[less] = ak; 1490 | ++less; 1491 | } else { // a[k] > pivot - Move a[k] to right part 1492 | while (a[great] > pivot) { 1493 | --great; 1494 | } 1495 | if (a[great] < pivot) { // a[great] <= pivot 1496 | a[k] = a[less]; 1497 | a[less] = a[great]; 1498 | ++less; 1499 | } else { // a[great] == pivot 1500 | /* 1501 | * Even though a[great] equals to pivot, the 1502 | * assignment a[k] = pivot may be incorrect, 1503 | * if a[great] and pivot are floating-point 1504 | * zeros of different signs. Therefore in float 1505 | * and double sorting methods we have to use 1506 | * more accurate assignment a[k] = a[great]. 1507 | */ 1508 | a[k] = pivot; 1509 | } 1510 | a[great] = ak; 1511 | --great; 1512 | } 1513 | } 1514 | 1515 | /* 1516 | * Sort left and right parts recursively. 1517 | * All elements from center part are equal 1518 | * and, therefore, already sorted. 1519 | */ 1520 | sort(a, left, less - 1, leftmost); 1521 | sort(a, great + 1, right, false); 1522 | } 1523 | } 1524 | 1525 | /** 1526 | * Sorts the specified range of the array using the given 1527 | * workspace array slice if possible for merging 1528 | * 1529 | * @param a the array to be sorted 1530 | * @param left the index of the first element, inclusive, to be sorted 1531 | * @param right the index of the last element, inclusive, to be sorted 1532 | * @param work a workspace array (slice) 1533 | * @param workBase origin of usable space in work array 1534 | * @param workLen usable size of work array 1535 | */ 1536 | static void sort(char[] a, int left, int right, 1537 | char[] work, int workBase, int workLen) { 1538 | // Use counting sort on large arrays 1539 | if (right - left > COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR) { 1540 | int[] count = new int[NUM_CHAR_VALUES]; 1541 | 1542 | for (int i = left - 1; ++i <= right; 1543 | count[a[i]]++ 1544 | ); 1545 | for (int i = NUM_CHAR_VALUES, k = right + 1; k > left; ) { 1546 | while (count[--i] == 0); 1547 | char value = (char) i; 1548 | int s = count[i]; 1549 | 1550 | do { 1551 | a[--k] = value; 1552 | } while (--s > 0); 1553 | } 1554 | } else { // Use Dual-Pivot Quicksort on small arrays 1555 | doSort(a, left, right, work, workBase, workLen); 1556 | } 1557 | } 1558 | 1559 | /** The number of distinct char values. */ 1560 | private static final int NUM_CHAR_VALUES = 1 << 16; 1561 | 1562 | /** 1563 | * Sorts the specified range of the array. 1564 | * 1565 | * @param a the array to be sorted 1566 | * @param left the index of the first element, inclusive, to be sorted 1567 | * @param right the index of the last element, inclusive, to be sorted 1568 | * @param work a workspace array (slice) 1569 | * @param workBase origin of usable space in work array 1570 | * @param workLen usable size of work array 1571 | */ 1572 | private static void doSort(char[] a, int left, int right, 1573 | char[] work, int workBase, int workLen) { 1574 | // Use Quicksort on small arrays 1575 | if (right - left < QUICKSORT_THRESHOLD) { 1576 | sort(a, left, right, true); 1577 | return; 1578 | } 1579 | 1580 | /* 1581 | * Index run[i] is the start of i-th run 1582 | * (ascending or descending sequence). 1583 | */ 1584 | int[] run = new int[MAX_RUN_COUNT + 1]; 1585 | int count = 0; run[0] = left; 1586 | 1587 | // Check if the array is nearly sorted 1588 | for (int k = left; k < right; run[count] = k) { 1589 | // Equal items in the beginning of the sequence 1590 | while (k < right && a[k] == a[k + 1]) 1591 | k++; 1592 | if (k == right) break; // Sequence finishes with equal items 1593 | if (a[k] < a[k + 1]) { // ascending 1594 | while (++k <= right && a[k - 1] <= a[k]); 1595 | } else if (a[k] > a[k + 1]) { // descending 1596 | while (++k <= right && a[k - 1] >= a[k]); 1597 | // Transform into an ascending sequence 1598 | for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) { 1599 | char t = a[lo]; a[lo] = a[hi]; a[hi] = t; 1600 | } 1601 | } 1602 | 1603 | // Merge a transformed descending sequence followed by an 1604 | // ascending sequence 1605 | if (run[count] > left && a[run[count]] >= a[run[count] - 1]) { 1606 | count--; 1607 | } 1608 | 1609 | /* 1610 | * The array is not highly structured, 1611 | * use Quicksort instead of merge sort. 1612 | */ 1613 | if (++count == MAX_RUN_COUNT) { 1614 | sort(a, left, right, true); 1615 | return; 1616 | } 1617 | } 1618 | 1619 | // These invariants should hold true: 1620 | // run[0] = 0 1621 | // run[] = right + 1; (terminator) 1622 | 1623 | if (count == 0) { 1624 | // A single equal run 1625 | return; 1626 | } else if (count == 1 && run[count] > right) { 1627 | // Either a single ascending or a transformed descending run. 1628 | // Always check that a final run is a proper terminator, otherwise 1629 | // we have an unterminated trailing run, to handle downstream. 1630 | return; 1631 | } 1632 | right++; 1633 | if (run[count] < right) { 1634 | // Corner case: the final run is not a terminator. This may happen 1635 | // if a final run is an equals run, or there is a single-element run 1636 | // at the end. Fix up by adding a proper terminator at the end. 1637 | // Note that we terminate with (right + 1), incremented earlier. 1638 | run[++count] = right; 1639 | } 1640 | 1641 | // Determine alternation base for merge 1642 | byte odd = 0; 1643 | for (int n = 1; (n <<= 1) < count; odd ^= 1); 1644 | 1645 | // Use or create temporary array b for merging 1646 | char[] b; // temp array; alternates with a 1647 | int ao, bo; // array offsets from 'left' 1648 | int blen = right - left; // space needed for b 1649 | if (work == null || workLen < blen || workBase + blen > work.length) { 1650 | work = new char[blen]; 1651 | workBase = 0; 1652 | } 1653 | if (odd == 0) { 1654 | System.arraycopy(a, left, work, workBase, blen); 1655 | b = a; 1656 | bo = 0; 1657 | a = work; 1658 | ao = workBase - left; 1659 | } else { 1660 | b = work; 1661 | ao = 0; 1662 | bo = workBase - left; 1663 | } 1664 | 1665 | // Merging 1666 | for (int last; count > 1; count = last) { 1667 | for (int k = (last = 0) + 2; k <= count; k += 2) { 1668 | int hi = run[k], mi = run[k - 1]; 1669 | for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) { 1670 | if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) { 1671 | b[i + bo] = a[p++ + ao]; 1672 | } else { 1673 | b[i + bo] = a[q++ + ao]; 1674 | } 1675 | } 1676 | run[++last] = hi; 1677 | } 1678 | if ((count & 1) != 0) { 1679 | for (int i = right, lo = run[count - 1]; --i >= lo; 1680 | b[i + bo] = a[i + ao] 1681 | ); 1682 | run[++last] = right; 1683 | } 1684 | char[] t = a; a = b; b = t; 1685 | int o = ao; ao = bo; bo = o; 1686 | } 1687 | } 1688 | 1689 | /** 1690 | * Sorts the specified range of the array by Dual-Pivot Quicksort. 1691 | * 1692 | * @param a the array to be sorted 1693 | * @param left the index of the first element, inclusive, to be sorted 1694 | * @param right the index of the last element, inclusive, to be sorted 1695 | * @param leftmost indicates if this part is the leftmost in the range 1696 | */ 1697 | private static void sort(char[] a, int left, int right, boolean leftmost) { 1698 | int length = right - left + 1; 1699 | 1700 | // Use insertion sort on tiny arrays 1701 | if (length < INSERTION_SORT_THRESHOLD) { 1702 | if (leftmost) { 1703 | /* 1704 | * Traditional (without sentinel) insertion sort, 1705 | * optimized for server VM, is used in case of 1706 | * the leftmost part. 1707 | */ 1708 | for (int i = left, j = i; i < right; j = ++i) { 1709 | char ai = a[i + 1]; 1710 | while (ai < a[j]) { 1711 | a[j + 1] = a[j]; 1712 | if (j-- == left) { 1713 | break; 1714 | } 1715 | } 1716 | a[j + 1] = ai; 1717 | } 1718 | } else { 1719 | /* 1720 | * Skip the longest ascending sequence. 1721 | */ 1722 | do { 1723 | if (left >= right) { 1724 | return; 1725 | } 1726 | } while (a[++left] >= a[left - 1]); 1727 | 1728 | /* 1729 | * Every element from adjoining part plays the role 1730 | * of sentinel, therefore this allows us to avoid the 1731 | * left range check on each iteration. Moreover, we use 1732 | * the more optimized algorithm, so called pair insertion 1733 | * sort, which is faster (in the context of Quicksort) 1734 | * than traditional implementation of insertion sort. 1735 | */ 1736 | for (int k = left; ++left <= right; k = ++left) { 1737 | char a1 = a[k], a2 = a[left]; 1738 | 1739 | if (a1 < a2) { 1740 | a2 = a1; a1 = a[left]; 1741 | } 1742 | while (a1 < a[--k]) { 1743 | a[k + 2] = a[k]; 1744 | } 1745 | a[++k + 1] = a1; 1746 | 1747 | while (a2 < a[--k]) { 1748 | a[k + 1] = a[k]; 1749 | } 1750 | a[k + 1] = a2; 1751 | } 1752 | char last = a[right]; 1753 | 1754 | while (last < a[--right]) { 1755 | a[right + 1] = a[right]; 1756 | } 1757 | a[right + 1] = last; 1758 | } 1759 | return; 1760 | } 1761 | 1762 | // Inexpensive approximation of length / 7 1763 | int seventh = (length >> 3) + (length >> 6) + 1; 1764 | 1765 | /* 1766 | * Sort five evenly spaced elements around (and including) the 1767 | * center element in the range. These elements will be used for 1768 | * pivot selection as described below. The choice for spacing 1769 | * these elements was empirically determined to work well on 1770 | * a wide variety of inputs. 1771 | */ 1772 | int e3 = (left + right) >>> 1; // The midpoint 1773 | int e2 = e3 - seventh; 1774 | int e1 = e2 - seventh; 1775 | int e4 = e3 + seventh; 1776 | int e5 = e4 + seventh; 1777 | 1778 | // Sort these elements using insertion sort 1779 | if (a[e2] < a[e1]) { char t = a[e2]; a[e2] = a[e1]; a[e1] = t; } 1780 | 1781 | if (a[e3] < a[e2]) { char t = a[e3]; a[e3] = a[e2]; a[e2] = t; 1782 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 1783 | } 1784 | if (a[e4] < a[e3]) { char t = a[e4]; a[e4] = a[e3]; a[e3] = t; 1785 | if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; 1786 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 1787 | } 1788 | } 1789 | if (a[e5] < a[e4]) { char t = a[e5]; a[e5] = a[e4]; a[e4] = t; 1790 | if (t < a[e3]) { a[e4] = a[e3]; a[e3] = t; 1791 | if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; 1792 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 1793 | } 1794 | } 1795 | } 1796 | 1797 | // Pointers 1798 | int less = left; // The index of the first element of center part 1799 | int great = right; // The index before the first element of right part 1800 | 1801 | if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) { 1802 | /* 1803 | * Use the second and fourth of the five sorted elements as pivots. 1804 | * These values are inexpensive approximations of the first and 1805 | * second terciles of the array. Note that pivot1 <= pivot2. 1806 | */ 1807 | char pivot1 = a[e2]; 1808 | char pivot2 = a[e4]; 1809 | 1810 | /* 1811 | * The first and the last elements to be sorted are moved to the 1812 | * locations formerly occupied by the pivots. When partitioning 1813 | * is complete, the pivots are swapped back into their final 1814 | * positions, and excluded from subsequent sorting. 1815 | */ 1816 | a[e2] = a[left]; 1817 | a[e4] = a[right]; 1818 | 1819 | /* 1820 | * Skip elements, which are less or greater than pivot values. 1821 | */ 1822 | while (a[++less] < pivot1); 1823 | while (a[--great] > pivot2); 1824 | 1825 | /* 1826 | * Partitioning: 1827 | * 1828 | * left part center part right part 1829 | * +--------------------------------------------------------------+ 1830 | * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 | 1831 | * +--------------------------------------------------------------+ 1832 | * ^ ^ ^ 1833 | * | | | 1834 | * less k great 1835 | * 1836 | * Invariants: 1837 | * 1838 | * all in (left, less) < pivot1 1839 | * pivot1 <= all in [less, k) <= pivot2 1840 | * all in (great, right) > pivot2 1841 | * 1842 | * Pointer k is the first index of ?-part. 1843 | */ 1844 | outer: 1845 | for (int k = less - 1; ++k <= great; ) { 1846 | char ak = a[k]; 1847 | if (ak < pivot1) { // Move a[k] to left part 1848 | a[k] = a[less]; 1849 | /* 1850 | * Here and below we use "a[i] = b; i++;" instead 1851 | * of "a[i++] = b;" due to performance issue. 1852 | */ 1853 | a[less] = ak; 1854 | ++less; 1855 | } else if (ak > pivot2) { // Move a[k] to right part 1856 | while (a[great] > pivot2) { 1857 | if (great-- == k) { 1858 | break outer; 1859 | } 1860 | } 1861 | if (a[great] < pivot1) { // a[great] <= pivot2 1862 | a[k] = a[less]; 1863 | a[less] = a[great]; 1864 | ++less; 1865 | } else { // pivot1 <= a[great] <= pivot2 1866 | a[k] = a[great]; 1867 | } 1868 | /* 1869 | * Here and below we use "a[i] = b; i--;" instead 1870 | * of "a[i--] = b;" due to performance issue. 1871 | */ 1872 | a[great] = ak; 1873 | --great; 1874 | } 1875 | } 1876 | 1877 | // Swap pivots into their final positions 1878 | a[left] = a[less - 1]; a[less - 1] = pivot1; 1879 | a[right] = a[great + 1]; a[great + 1] = pivot2; 1880 | 1881 | // Sort left and right parts recursively, excluding known pivots 1882 | sort(a, left, less - 2, leftmost); 1883 | sort(a, great + 2, right, false); 1884 | 1885 | /* 1886 | * If center part is too large (comprises > 4/7 of the array), 1887 | * swap internal pivot values to ends. 1888 | */ 1889 | if (less < e1 && e5 < great) { 1890 | /* 1891 | * Skip elements, which are equal to pivot values. 1892 | */ 1893 | while (a[less] == pivot1) { 1894 | ++less; 1895 | } 1896 | 1897 | while (a[great] == pivot2) { 1898 | --great; 1899 | } 1900 | 1901 | /* 1902 | * Partitioning: 1903 | * 1904 | * left part center part right part 1905 | * +----------------------------------------------------------+ 1906 | * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 | 1907 | * +----------------------------------------------------------+ 1908 | * ^ ^ ^ 1909 | * | | | 1910 | * less k great 1911 | * 1912 | * Invariants: 1913 | * 1914 | * all in (*, less) == pivot1 1915 | * pivot1 < all in [less, k) < pivot2 1916 | * all in (great, *) == pivot2 1917 | * 1918 | * Pointer k is the first index of ?-part. 1919 | */ 1920 | outer: 1921 | for (int k = less - 1; ++k <= great; ) { 1922 | char ak = a[k]; 1923 | if (ak == pivot1) { // Move a[k] to left part 1924 | a[k] = a[less]; 1925 | a[less] = ak; 1926 | ++less; 1927 | } else if (ak == pivot2) { // Move a[k] to right part 1928 | while (a[great] == pivot2) { 1929 | if (great-- == k) { 1930 | break outer; 1931 | } 1932 | } 1933 | if (a[great] == pivot1) { // a[great] < pivot2 1934 | a[k] = a[less]; 1935 | /* 1936 | * Even though a[great] equals to pivot1, the 1937 | * assignment a[less] = pivot1 may be incorrect, 1938 | * if a[great] and pivot1 are floating-point zeros 1939 | * of different signs. Therefore in float and 1940 | * double sorting methods we have to use more 1941 | * accurate assignment a[less] = a[great]. 1942 | */ 1943 | a[less] = pivot1; 1944 | ++less; 1945 | } else { // pivot1 < a[great] < pivot2 1946 | a[k] = a[great]; 1947 | } 1948 | a[great] = ak; 1949 | --great; 1950 | } 1951 | } 1952 | } 1953 | 1954 | // Sort center part recursively 1955 | sort(a, less, great, false); 1956 | 1957 | } else { // Partitioning with one pivot 1958 | /* 1959 | * Use the third of the five sorted elements as pivot. 1960 | * This value is inexpensive approximation of the median. 1961 | */ 1962 | char pivot = a[e3]; 1963 | 1964 | /* 1965 | * Partitioning degenerates to the traditional 3-way 1966 | * (or "Dutch National Flag") schema: 1967 | * 1968 | * left part center part right part 1969 | * +-------------------------------------------------+ 1970 | * | < pivot | == pivot | ? | > pivot | 1971 | * +-------------------------------------------------+ 1972 | * ^ ^ ^ 1973 | * | | | 1974 | * less k great 1975 | * 1976 | * Invariants: 1977 | * 1978 | * all in (left, less) < pivot 1979 | * all in [less, k) == pivot 1980 | * all in (great, right) > pivot 1981 | * 1982 | * Pointer k is the first index of ?-part. 1983 | */ 1984 | for (int k = less; k <= great; ++k) { 1985 | if (a[k] == pivot) { 1986 | continue; 1987 | } 1988 | char ak = a[k]; 1989 | if (ak < pivot) { // Move a[k] to left part 1990 | a[k] = a[less]; 1991 | a[less] = ak; 1992 | ++less; 1993 | } else { // a[k] > pivot - Move a[k] to right part 1994 | while (a[great] > pivot) { 1995 | --great; 1996 | } 1997 | if (a[great] < pivot) { // a[great] <= pivot 1998 | a[k] = a[less]; 1999 | a[less] = a[great]; 2000 | ++less; 2001 | } else { // a[great] == pivot 2002 | /* 2003 | * Even though a[great] equals to pivot, the 2004 | * assignment a[k] = pivot may be incorrect, 2005 | * if a[great] and pivot are floating-point 2006 | * zeros of different signs. Therefore in float 2007 | * and double sorting methods we have to use 2008 | * more accurate assignment a[k] = a[great]. 2009 | */ 2010 | a[k] = pivot; 2011 | } 2012 | a[great] = ak; 2013 | --great; 2014 | } 2015 | } 2016 | 2017 | /* 2018 | * Sort left and right parts recursively. 2019 | * All elements from center part are equal 2020 | * and, therefore, already sorted. 2021 | */ 2022 | sort(a, left, less - 1, leftmost); 2023 | sort(a, great + 1, right, false); 2024 | } 2025 | } 2026 | 2027 | /** The number of distinct byte values. */ 2028 | private static final int NUM_BYTE_VALUES = 1 << 8; 2029 | 2030 | /** 2031 | * Sorts the specified range of the array. 2032 | * 2033 | * @param a the array to be sorted 2034 | * @param left the index of the first element, inclusive, to be sorted 2035 | * @param right the index of the last element, inclusive, to be sorted 2036 | */ 2037 | static void sort(byte[] a, int left, int right) { 2038 | // Use counting sort on large arrays 2039 | if (right - left > COUNTING_SORT_THRESHOLD_FOR_BYTE) { 2040 | int[] count = new int[NUM_BYTE_VALUES]; 2041 | 2042 | for (int i = left - 1; ++i <= right; 2043 | count[a[i] - Byte.MIN_VALUE]++ 2044 | ); 2045 | for (int i = NUM_BYTE_VALUES, k = right + 1; k > left; ) { 2046 | while (count[--i] == 0); 2047 | byte value = (byte) (i + Byte.MIN_VALUE); 2048 | int s = count[i]; 2049 | 2050 | do { 2051 | a[--k] = value; 2052 | } while (--s > 0); 2053 | } 2054 | } else { // Use insertion sort on small arrays 2055 | for (int i = left, j = i; i < right; j = ++i) { 2056 | byte ai = a[i + 1]; 2057 | while (ai < a[j]) { 2058 | a[j + 1] = a[j]; 2059 | if (j-- == left) { 2060 | break; 2061 | } 2062 | } 2063 | a[j + 1] = ai; 2064 | } 2065 | } 2066 | } 2067 | 2068 | /** 2069 | * Sorts the specified range of the array using the given 2070 | * workspace array slice if possible for merging 2071 | * 2072 | * @param a the array to be sorted 2073 | * @param left the index of the first element, inclusive, to be sorted 2074 | * @param right the index of the last element, inclusive, to be sorted 2075 | * @param work a workspace array (slice) 2076 | * @param workBase origin of usable space in work array 2077 | * @param workLen usable size of work array 2078 | */ 2079 | static void sort(float[] a, int left, int right, 2080 | float[] work, int workBase, int workLen) { 2081 | /* 2082 | * Phase 1: Move NaNs to the end of the array. 2083 | */ 2084 | while (left <= right && Float.isNaN(a[right])) { 2085 | --right; 2086 | } 2087 | for (int k = right; --k >= left; ) { 2088 | float ak = a[k]; 2089 | if (ak != ak) { // a[k] is NaN 2090 | a[k] = a[right]; 2091 | a[right] = ak; 2092 | --right; 2093 | } 2094 | } 2095 | 2096 | /* 2097 | * Phase 2: Sort everything except NaNs (which are already in place). 2098 | */ 2099 | doSort(a, left, right, work, workBase, workLen); 2100 | 2101 | /* 2102 | * Phase 3: Place negative zeros before positive zeros. 2103 | */ 2104 | int hi = right; 2105 | 2106 | /* 2107 | * Find the first zero, or first positive, or last negative element. 2108 | */ 2109 | while (left < hi) { 2110 | int middle = (left + hi) >>> 1; 2111 | float middleValue = a[middle]; 2112 | 2113 | if (middleValue < 0.0f) { 2114 | left = middle + 1; 2115 | } else { 2116 | hi = middle; 2117 | } 2118 | } 2119 | 2120 | /* 2121 | * Skip the last negative value (if any) or all leading negative zeros. 2122 | */ 2123 | while (left <= right && Float.floatToRawIntBits(a[left]) < 0) { 2124 | ++left; 2125 | } 2126 | 2127 | /* 2128 | * Move negative zeros to the beginning of the sub-range. 2129 | * 2130 | * Partitioning: 2131 | * 2132 | * +----------------------------------------------------+ 2133 | * | < 0.0 | -0.0 | 0.0 | ? ( >= 0.0 ) | 2134 | * +----------------------------------------------------+ 2135 | * ^ ^ ^ 2136 | * | | | 2137 | * left p k 2138 | * 2139 | * Invariants: 2140 | * 2141 | * all in (*, left) < 0.0 2142 | * all in [left, p) == -0.0 2143 | * all in [p, k) == 0.0 2144 | * all in [k, right] >= 0.0 2145 | * 2146 | * Pointer k is the first index of ?-part. 2147 | */ 2148 | for (int k = left, p = left - 1; ++k <= right; ) { 2149 | float ak = a[k]; 2150 | if (ak != 0.0f) { 2151 | break; 2152 | } 2153 | if (Float.floatToRawIntBits(ak) < 0) { // ak is -0.0f 2154 | a[k] = 0.0f; 2155 | a[++p] = -0.0f; 2156 | } 2157 | } 2158 | } 2159 | 2160 | /** 2161 | * Sorts the specified range of the array. 2162 | * 2163 | * @param a the array to be sorted 2164 | * @param left the index of the first element, inclusive, to be sorted 2165 | * @param right the index of the last element, inclusive, to be sorted 2166 | * @param work a workspace array (slice) 2167 | * @param workBase origin of usable space in work array 2168 | * @param workLen usable size of work array 2169 | */ 2170 | private static void doSort(float[] a, int left, int right, 2171 | float[] work, int workBase, int workLen) { 2172 | // Use Quicksort on small arrays 2173 | if (right - left < QUICKSORT_THRESHOLD) { 2174 | sort(a, left, right, true); 2175 | return; 2176 | } 2177 | 2178 | /* 2179 | * Index run[i] is the start of i-th run 2180 | * (ascending or descending sequence). 2181 | */ 2182 | int[] run = new int[MAX_RUN_COUNT + 1]; 2183 | int count = 0; run[0] = left; 2184 | 2185 | // Check if the array is nearly sorted 2186 | for (int k = left; k < right; run[count] = k) { 2187 | // Equal items in the beginning of the sequence 2188 | while (k < right && a[k] == a[k + 1]) 2189 | k++; 2190 | if (k == right) break; // Sequence finishes with equal items 2191 | if (a[k] < a[k + 1]) { // ascending 2192 | while (++k <= right && a[k - 1] <= a[k]); 2193 | } else if (a[k] > a[k + 1]) { // descending 2194 | while (++k <= right && a[k - 1] >= a[k]); 2195 | // Transform into an ascending sequence 2196 | for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) { 2197 | float t = a[lo]; a[lo] = a[hi]; a[hi] = t; 2198 | } 2199 | } 2200 | 2201 | // Merge a transformed descending sequence followed by an 2202 | // ascending sequence 2203 | if (run[count] > left && a[run[count]] >= a[run[count] - 1]) { 2204 | count--; 2205 | } 2206 | 2207 | /* 2208 | * The array is not highly structured, 2209 | * use Quicksort instead of merge sort. 2210 | */ 2211 | if (++count == MAX_RUN_COUNT) { 2212 | sort(a, left, right, true); 2213 | return; 2214 | } 2215 | } 2216 | 2217 | // These invariants should hold true: 2218 | // run[0] = 0 2219 | // run[] = right + 1; (terminator) 2220 | 2221 | if (count == 0) { 2222 | // A single equal run 2223 | return; 2224 | } else if (count == 1 && run[count] > right) { 2225 | // Either a single ascending or a transformed descending run. 2226 | // Always check that a final run is a proper terminator, otherwise 2227 | // we have an unterminated trailing run, to handle downstream. 2228 | return; 2229 | } 2230 | right++; 2231 | if (run[count] < right) { 2232 | // Corner case: the final run is not a terminator. This may happen 2233 | // if a final run is an equals run, or there is a single-element run 2234 | // at the end. Fix up by adding a proper terminator at the end. 2235 | // Note that we terminate with (right + 1), incremented earlier. 2236 | run[++count] = right; 2237 | } 2238 | 2239 | // Determine alternation base for merge 2240 | byte odd = 0; 2241 | for (int n = 1; (n <<= 1) < count; odd ^= 1); 2242 | 2243 | // Use or create temporary array b for merging 2244 | float[] b; // temp array; alternates with a 2245 | int ao, bo; // array offsets from 'left' 2246 | int blen = right - left; // space needed for b 2247 | if (work == null || workLen < blen || workBase + blen > work.length) { 2248 | work = new float[blen]; 2249 | workBase = 0; 2250 | } 2251 | if (odd == 0) { 2252 | System.arraycopy(a, left, work, workBase, blen); 2253 | b = a; 2254 | bo = 0; 2255 | a = work; 2256 | ao = workBase - left; 2257 | } else { 2258 | b = work; 2259 | ao = 0; 2260 | bo = workBase - left; 2261 | } 2262 | 2263 | // Merging 2264 | for (int last; count > 1; count = last) { 2265 | for (int k = (last = 0) + 2; k <= count; k += 2) { 2266 | int hi = run[k], mi = run[k - 1]; 2267 | for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) { 2268 | if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) { 2269 | b[i + bo] = a[p++ + ao]; 2270 | } else { 2271 | b[i + bo] = a[q++ + ao]; 2272 | } 2273 | } 2274 | run[++last] = hi; 2275 | } 2276 | if ((count & 1) != 0) { 2277 | for (int i = right, lo = run[count - 1]; --i >= lo; 2278 | b[i + bo] = a[i + ao] 2279 | ); 2280 | run[++last] = right; 2281 | } 2282 | float[] t = a; a = b; b = t; 2283 | int o = ao; ao = bo; bo = o; 2284 | } 2285 | } 2286 | 2287 | /** 2288 | * Sorts the specified range of the array by Dual-Pivot Quicksort. 2289 | * 2290 | * @param a the array to be sorted 2291 | * @param left the index of the first element, inclusive, to be sorted 2292 | * @param right the index of the last element, inclusive, to be sorted 2293 | * @param leftmost indicates if this part is the leftmost in the range 2294 | */ 2295 | private static void sort(float[] a, int left, int right, boolean leftmost) { 2296 | int length = right - left + 1; 2297 | 2298 | // Use insertion sort on tiny arrays 2299 | if (length < INSERTION_SORT_THRESHOLD) { 2300 | if (leftmost) { 2301 | /* 2302 | * Traditional (without sentinel) insertion sort, 2303 | * optimized for server VM, is used in case of 2304 | * the leftmost part. 2305 | */ 2306 | for (int i = left, j = i; i < right; j = ++i) { 2307 | float ai = a[i + 1]; 2308 | while (ai < a[j]) { 2309 | a[j + 1] = a[j]; 2310 | if (j-- == left) { 2311 | break; 2312 | } 2313 | } 2314 | a[j + 1] = ai; 2315 | } 2316 | } else { 2317 | /* 2318 | * Skip the longest ascending sequence. 2319 | */ 2320 | do { 2321 | if (left >= right) { 2322 | return; 2323 | } 2324 | } while (a[++left] >= a[left - 1]); 2325 | 2326 | /* 2327 | * Every element from adjoining part plays the role 2328 | * of sentinel, therefore this allows us to avoid the 2329 | * left range check on each iteration. Moreover, we use 2330 | * the more optimized algorithm, so called pair insertion 2331 | * sort, which is faster (in the context of Quicksort) 2332 | * than traditional implementation of insertion sort. 2333 | */ 2334 | for (int k = left; ++left <= right; k = ++left) { 2335 | float a1 = a[k], a2 = a[left]; 2336 | 2337 | if (a1 < a2) { 2338 | a2 = a1; a1 = a[left]; 2339 | } 2340 | while (a1 < a[--k]) { 2341 | a[k + 2] = a[k]; 2342 | } 2343 | a[++k + 1] = a1; 2344 | 2345 | while (a2 < a[--k]) { 2346 | a[k + 1] = a[k]; 2347 | } 2348 | a[k + 1] = a2; 2349 | } 2350 | float last = a[right]; 2351 | 2352 | while (last < a[--right]) { 2353 | a[right + 1] = a[right]; 2354 | } 2355 | a[right + 1] = last; 2356 | } 2357 | return; 2358 | } 2359 | 2360 | // Inexpensive approximation of length / 7 2361 | int seventh = (length >> 3) + (length >> 6) + 1; 2362 | 2363 | /* 2364 | * Sort five evenly spaced elements around (and including) the 2365 | * center element in the range. These elements will be used for 2366 | * pivot selection as described below. The choice for spacing 2367 | * these elements was empirically determined to work well on 2368 | * a wide variety of inputs. 2369 | */ 2370 | int e3 = (left + right) >>> 1; // The midpoint 2371 | int e2 = e3 - seventh; 2372 | int e1 = e2 - seventh; 2373 | int e4 = e3 + seventh; 2374 | int e5 = e4 + seventh; 2375 | 2376 | // Sort these elements using insertion sort 2377 | if (a[e2] < a[e1]) { float t = a[e2]; a[e2] = a[e1]; a[e1] = t; } 2378 | 2379 | if (a[e3] < a[e2]) { float t = a[e3]; a[e3] = a[e2]; a[e2] = t; 2380 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 2381 | } 2382 | if (a[e4] < a[e3]) { float t = a[e4]; a[e4] = a[e3]; a[e3] = t; 2383 | if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; 2384 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 2385 | } 2386 | } 2387 | if (a[e5] < a[e4]) { float t = a[e5]; a[e5] = a[e4]; a[e4] = t; 2388 | if (t < a[e3]) { a[e4] = a[e3]; a[e3] = t; 2389 | if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; 2390 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 2391 | } 2392 | } 2393 | } 2394 | 2395 | // Pointers 2396 | int less = left; // The index of the first element of center part 2397 | int great = right; // The index before the first element of right part 2398 | 2399 | if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) { 2400 | /* 2401 | * Use the second and fourth of the five sorted elements as pivots. 2402 | * These values are inexpensive approximations of the first and 2403 | * second terciles of the array. Note that pivot1 <= pivot2. 2404 | */ 2405 | float pivot1 = a[e2]; 2406 | float pivot2 = a[e4]; 2407 | 2408 | /* 2409 | * The first and the last elements to be sorted are moved to the 2410 | * locations formerly occupied by the pivots. When partitioning 2411 | * is complete, the pivots are swapped back into their final 2412 | * positions, and excluded from subsequent sorting. 2413 | */ 2414 | a[e2] = a[left]; 2415 | a[e4] = a[right]; 2416 | 2417 | /* 2418 | * Skip elements, which are less or greater than pivot values. 2419 | */ 2420 | while (a[++less] < pivot1); 2421 | while (a[--great] > pivot2); 2422 | 2423 | /* 2424 | * Partitioning: 2425 | * 2426 | * left part center part right part 2427 | * +--------------------------------------------------------------+ 2428 | * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 | 2429 | * +--------------------------------------------------------------+ 2430 | * ^ ^ ^ 2431 | * | | | 2432 | * less k great 2433 | * 2434 | * Invariants: 2435 | * 2436 | * all in (left, less) < pivot1 2437 | * pivot1 <= all in [less, k) <= pivot2 2438 | * all in (great, right) > pivot2 2439 | * 2440 | * Pointer k is the first index of ?-part. 2441 | */ 2442 | outer: 2443 | for (int k = less - 1; ++k <= great; ) { 2444 | float ak = a[k]; 2445 | if (ak < pivot1) { // Move a[k] to left part 2446 | a[k] = a[less]; 2447 | /* 2448 | * Here and below we use "a[i] = b; i++;" instead 2449 | * of "a[i++] = b;" due to performance issue. 2450 | */ 2451 | a[less] = ak; 2452 | ++less; 2453 | } else if (ak > pivot2) { // Move a[k] to right part 2454 | while (a[great] > pivot2) { 2455 | if (great-- == k) { 2456 | break outer; 2457 | } 2458 | } 2459 | if (a[great] < pivot1) { // a[great] <= pivot2 2460 | a[k] = a[less]; 2461 | a[less] = a[great]; 2462 | ++less; 2463 | } else { // pivot1 <= a[great] <= pivot2 2464 | a[k] = a[great]; 2465 | } 2466 | /* 2467 | * Here and below we use "a[i] = b; i--;" instead 2468 | * of "a[i--] = b;" due to performance issue. 2469 | */ 2470 | a[great] = ak; 2471 | --great; 2472 | } 2473 | } 2474 | 2475 | // Swap pivots into their final positions 2476 | a[left] = a[less - 1]; a[less - 1] = pivot1; 2477 | a[right] = a[great + 1]; a[great + 1] = pivot2; 2478 | 2479 | // Sort left and right parts recursively, excluding known pivots 2480 | sort(a, left, less - 2, leftmost); 2481 | sort(a, great + 2, right, false); 2482 | 2483 | /* 2484 | * If center part is too large (comprises > 4/7 of the array), 2485 | * swap internal pivot values to ends. 2486 | */ 2487 | if (less < e1 && e5 < great) { 2488 | /* 2489 | * Skip elements, which are equal to pivot values. 2490 | */ 2491 | while (a[less] == pivot1) { 2492 | ++less; 2493 | } 2494 | 2495 | while (a[great] == pivot2) { 2496 | --great; 2497 | } 2498 | 2499 | /* 2500 | * Partitioning: 2501 | * 2502 | * left part center part right part 2503 | * +----------------------------------------------------------+ 2504 | * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 | 2505 | * +----------------------------------------------------------+ 2506 | * ^ ^ ^ 2507 | * | | | 2508 | * less k great 2509 | * 2510 | * Invariants: 2511 | * 2512 | * all in (*, less) == pivot1 2513 | * pivot1 < all in [less, k) < pivot2 2514 | * all in (great, *) == pivot2 2515 | * 2516 | * Pointer k is the first index of ?-part. 2517 | */ 2518 | outer: 2519 | for (int k = less - 1; ++k <= great; ) { 2520 | float ak = a[k]; 2521 | if (ak == pivot1) { // Move a[k] to left part 2522 | a[k] = a[less]; 2523 | a[less] = ak; 2524 | ++less; 2525 | } else if (ak == pivot2) { // Move a[k] to right part 2526 | while (a[great] == pivot2) { 2527 | if (great-- == k) { 2528 | break outer; 2529 | } 2530 | } 2531 | if (a[great] == pivot1) { // a[great] < pivot2 2532 | a[k] = a[less]; 2533 | /* 2534 | * Even though a[great] equals to pivot1, the 2535 | * assignment a[less] = pivot1 may be incorrect, 2536 | * if a[great] and pivot1 are floating-point zeros 2537 | * of different signs. Therefore in float and 2538 | * double sorting methods we have to use more 2539 | * accurate assignment a[less] = a[great]. 2540 | */ 2541 | a[less] = a[great]; 2542 | ++less; 2543 | } else { // pivot1 < a[great] < pivot2 2544 | a[k] = a[great]; 2545 | } 2546 | a[great] = ak; 2547 | --great; 2548 | } 2549 | } 2550 | } 2551 | 2552 | // Sort center part recursively 2553 | sort(a, less, great, false); 2554 | 2555 | } else { // Partitioning with one pivot 2556 | /* 2557 | * Use the third of the five sorted elements as pivot. 2558 | * This value is inexpensive approximation of the median. 2559 | */ 2560 | float pivot = a[e3]; 2561 | 2562 | /* 2563 | * Partitioning degenerates to the traditional 3-way 2564 | * (or "Dutch National Flag") schema: 2565 | * 2566 | * left part center part right part 2567 | * +-------------------------------------------------+ 2568 | * | < pivot | == pivot | ? | > pivot | 2569 | * +-------------------------------------------------+ 2570 | * ^ ^ ^ 2571 | * | | | 2572 | * less k great 2573 | * 2574 | * Invariants: 2575 | * 2576 | * all in (left, less) < pivot 2577 | * all in [less, k) == pivot 2578 | * all in (great, right) > pivot 2579 | * 2580 | * Pointer k is the first index of ?-part. 2581 | */ 2582 | for (int k = less; k <= great; ++k) { 2583 | if (a[k] == pivot) { 2584 | continue; 2585 | } 2586 | float ak = a[k]; 2587 | if (ak < pivot) { // Move a[k] to left part 2588 | a[k] = a[less]; 2589 | a[less] = ak; 2590 | ++less; 2591 | } else { // a[k] > pivot - Move a[k] to right part 2592 | while (a[great] > pivot) { 2593 | --great; 2594 | } 2595 | if (a[great] < pivot) { // a[great] <= pivot 2596 | a[k] = a[less]; 2597 | a[less] = a[great]; 2598 | ++less; 2599 | } else { // a[great] == pivot 2600 | /* 2601 | * Even though a[great] equals to pivot, the 2602 | * assignment a[k] = pivot may be incorrect, 2603 | * if a[great] and pivot are floating-point 2604 | * zeros of different signs. Therefore in float 2605 | * and double sorting methods we have to use 2606 | * more accurate assignment a[k] = a[great]. 2607 | */ 2608 | a[k] = a[great]; 2609 | } 2610 | a[great] = ak; 2611 | --great; 2612 | } 2613 | } 2614 | 2615 | /* 2616 | * Sort left and right parts recursively. 2617 | * All elements from center part are equal 2618 | * and, therefore, already sorted. 2619 | */ 2620 | sort(a, left, less - 1, leftmost); 2621 | sort(a, great + 1, right, false); 2622 | } 2623 | } 2624 | 2625 | /** 2626 | * Sorts the specified range of the array using the given 2627 | * workspace array slice if possible for merging 2628 | * 2629 | * @param a the array to be sorted 2630 | * @param left the index of the first element, inclusive, to be sorted 2631 | * @param right the index of the last element, inclusive, to be sorted 2632 | * @param work a workspace array (slice) 2633 | * @param workBase origin of usable space in work array 2634 | * @param workLen usable size of work array 2635 | */ 2636 | static void sort(double[] a, int left, int right, 2637 | double[] work, int workBase, int workLen) { 2638 | /* 2639 | * Phase 1: Move NaNs to the end of the array. 2640 | */ 2641 | while (left <= right && Double.isNaN(a[right])) { 2642 | --right; 2643 | } 2644 | for (int k = right; --k >= left; ) { 2645 | double ak = a[k]; 2646 | if (ak != ak) { // a[k] is NaN 2647 | a[k] = a[right]; 2648 | a[right] = ak; 2649 | --right; 2650 | } 2651 | } 2652 | 2653 | /* 2654 | * Phase 2: Sort everything except NaNs (which are already in place). 2655 | */ 2656 | doSort(a, left, right, work, workBase, workLen); 2657 | 2658 | /* 2659 | * Phase 3: Place negative zeros before positive zeros. 2660 | */ 2661 | int hi = right; 2662 | 2663 | /* 2664 | * Find the first zero, or first positive, or last negative element. 2665 | */ 2666 | while (left < hi) { 2667 | int middle = (left + hi) >>> 1; 2668 | double middleValue = a[middle]; 2669 | 2670 | if (middleValue < 0.0d) { 2671 | left = middle + 1; 2672 | } else { 2673 | hi = middle; 2674 | } 2675 | } 2676 | 2677 | /* 2678 | * Skip the last negative value (if any) or all leading negative zeros. 2679 | */ 2680 | while (left <= right && Double.doubleToRawLongBits(a[left]) < 0) { 2681 | ++left; 2682 | } 2683 | 2684 | /* 2685 | * Move negative zeros to the beginning of the sub-range. 2686 | * 2687 | * Partitioning: 2688 | * 2689 | * +----------------------------------------------------+ 2690 | * | < 0.0 | -0.0 | 0.0 | ? ( >= 0.0 ) | 2691 | * +----------------------------------------------------+ 2692 | * ^ ^ ^ 2693 | * | | | 2694 | * left p k 2695 | * 2696 | * Invariants: 2697 | * 2698 | * all in (*, left) < 0.0 2699 | * all in [left, p) == -0.0 2700 | * all in [p, k) == 0.0 2701 | * all in [k, right] >= 0.0 2702 | * 2703 | * Pointer k is the first index of ?-part. 2704 | */ 2705 | for (int k = left, p = left - 1; ++k <= right; ) { 2706 | double ak = a[k]; 2707 | if (ak != 0.0d) { 2708 | break; 2709 | } 2710 | if (Double.doubleToRawLongBits(ak) < 0) { // ak is -0.0d 2711 | a[k] = 0.0d; 2712 | a[++p] = -0.0d; 2713 | } 2714 | } 2715 | } 2716 | 2717 | /** 2718 | * Sorts the specified range of the array. 2719 | * 2720 | * @param a the array to be sorted 2721 | * @param left the index of the first element, inclusive, to be sorted 2722 | * @param right the index of the last element, inclusive, to be sorted 2723 | * @param work a workspace array (slice) 2724 | * @param workBase origin of usable space in work array 2725 | * @param workLen usable size of work array 2726 | */ 2727 | private static void doSort(double[] a, int left, int right, 2728 | double[] work, int workBase, int workLen) { 2729 | // Use Quicksort on small arrays 2730 | if (right - left < QUICKSORT_THRESHOLD) { 2731 | sort(a, left, right, true); 2732 | return; 2733 | } 2734 | 2735 | /* 2736 | * Index run[i] is the start of i-th run 2737 | * (ascending or descending sequence). 2738 | */ 2739 | int[] run = new int[MAX_RUN_COUNT + 1]; 2740 | int count = 0; run[0] = left; 2741 | 2742 | // Check if the array is nearly sorted 2743 | for (int k = left; k < right; run[count] = k) { 2744 | // Equal items in the beginning of the sequence 2745 | while (k < right && a[k] == a[k + 1]) 2746 | k++; 2747 | if (k == right) break; // Sequence finishes with equal items 2748 | if (a[k] < a[k + 1]) { // ascending 2749 | while (++k <= right && a[k - 1] <= a[k]); 2750 | } else if (a[k] > a[k + 1]) { // descending 2751 | while (++k <= right && a[k - 1] >= a[k]); 2752 | // Transform into an ascending sequence 2753 | for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) { 2754 | double t = a[lo]; a[lo] = a[hi]; a[hi] = t; 2755 | } 2756 | } 2757 | 2758 | // Merge a transformed descending sequence followed by an 2759 | // ascending sequence 2760 | if (run[count] > left && a[run[count]] >= a[run[count] - 1]) { 2761 | count--; 2762 | } 2763 | 2764 | /* 2765 | * The array is not highly structured, 2766 | * use Quicksort instead of merge sort. 2767 | */ 2768 | if (++count == MAX_RUN_COUNT) { 2769 | sort(a, left, right, true); 2770 | return; 2771 | } 2772 | } 2773 | 2774 | // These invariants should hold true: 2775 | // run[0] = 0 2776 | // run[] = right + 1; (terminator) 2777 | 2778 | if (count == 0) { 2779 | // A single equal run 2780 | return; 2781 | } else if (count == 1 && run[count] > right) { 2782 | // Either a single ascending or a transformed descending run. 2783 | // Always check that a final run is a proper terminator, otherwise 2784 | // we have an unterminated trailing run, to handle downstream. 2785 | return; 2786 | } 2787 | right++; 2788 | if (run[count] < right) { 2789 | // Corner case: the final run is not a terminator. This may happen 2790 | // if a final run is an equals run, or there is a single-element run 2791 | // at the end. Fix up by adding a proper terminator at the end. 2792 | // Note that we terminate with (right + 1), incremented earlier. 2793 | run[++count] = right; 2794 | } 2795 | 2796 | // Determine alternation base for merge 2797 | byte odd = 0; 2798 | for (int n = 1; (n <<= 1) < count; odd ^= 1); 2799 | 2800 | // Use or create temporary array b for merging 2801 | double[] b; // temp array; alternates with a 2802 | int ao, bo; // array offsets from 'left' 2803 | int blen = right - left; // space needed for b 2804 | if (work == null || workLen < blen || workBase + blen > work.length) { 2805 | work = new double[blen]; 2806 | workBase = 0; 2807 | } 2808 | if (odd == 0) { 2809 | System.arraycopy(a, left, work, workBase, blen); 2810 | b = a; 2811 | bo = 0; 2812 | a = work; 2813 | ao = workBase - left; 2814 | } else { 2815 | b = work; 2816 | ao = 0; 2817 | bo = workBase - left; 2818 | } 2819 | 2820 | // Merging 2821 | for (int last; count > 1; count = last) { 2822 | for (int k = (last = 0) + 2; k <= count; k += 2) { 2823 | int hi = run[k], mi = run[k - 1]; 2824 | for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) { 2825 | if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) { 2826 | b[i + bo] = a[p++ + ao]; 2827 | } else { 2828 | b[i + bo] = a[q++ + ao]; 2829 | } 2830 | } 2831 | run[++last] = hi; 2832 | } 2833 | if ((count & 1) != 0) { 2834 | for (int i = right, lo = run[count - 1]; --i >= lo; 2835 | b[i + bo] = a[i + ao] 2836 | ); 2837 | run[++last] = right; 2838 | } 2839 | double[] t = a; a = b; b = t; 2840 | int o = ao; ao = bo; bo = o; 2841 | } 2842 | } 2843 | 2844 | /** 2845 | * Sorts the specified range of the array by Dual-Pivot Quicksort. 2846 | * 2847 | * @param a the array to be sorted 2848 | * @param left the index of the first element, inclusive, to be sorted 2849 | * @param right the index of the last element, inclusive, to be sorted 2850 | * @param leftmost indicates if this part is the leftmost in the range 2851 | */ 2852 | private static void sort(double[] a, int left, int right, boolean leftmost) { 2853 | int length = right - left + 1; 2854 | 2855 | // Use insertion sort on tiny arrays 2856 | if (length < INSERTION_SORT_THRESHOLD) { 2857 | if (leftmost) { 2858 | /* 2859 | * Traditional (without sentinel) insertion sort, 2860 | * optimized for server VM, is used in case of 2861 | * the leftmost part. 2862 | */ 2863 | for (int i = left, j = i; i < right; j = ++i) { 2864 | double ai = a[i + 1]; 2865 | while (ai < a[j]) { 2866 | a[j + 1] = a[j]; 2867 | if (j-- == left) { 2868 | break; 2869 | } 2870 | } 2871 | a[j + 1] = ai; 2872 | } 2873 | } else { 2874 | /* 2875 | * Skip the longest ascending sequence. 2876 | */ 2877 | do { 2878 | if (left >= right) { 2879 | return; 2880 | } 2881 | } while (a[++left] >= a[left - 1]); 2882 | 2883 | /* 2884 | * Every element from adjoining part plays the role 2885 | * of sentinel, therefore this allows us to avoid the 2886 | * left range check on each iteration. Moreover, we use 2887 | * the more optimized algorithm, so called pair insertion 2888 | * sort, which is faster (in the context of Quicksort) 2889 | * than traditional implementation of insertion sort. 2890 | */ 2891 | for (int k = left; ++left <= right; k = ++left) { 2892 | double a1 = a[k], a2 = a[left]; 2893 | 2894 | if (a1 < a2) { 2895 | a2 = a1; a1 = a[left]; 2896 | } 2897 | while (a1 < a[--k]) { 2898 | a[k + 2] = a[k]; 2899 | } 2900 | a[++k + 1] = a1; 2901 | 2902 | while (a2 < a[--k]) { 2903 | a[k + 1] = a[k]; 2904 | } 2905 | a[k + 1] = a2; 2906 | } 2907 | double last = a[right]; 2908 | 2909 | while (last < a[--right]) { 2910 | a[right + 1] = a[right]; 2911 | } 2912 | a[right + 1] = last; 2913 | } 2914 | return; 2915 | } 2916 | 2917 | // Inexpensive approximation of length / 7 2918 | int seventh = (length >> 3) + (length >> 6) + 1; 2919 | 2920 | /* 2921 | * Sort five evenly spaced elements around (and including) the 2922 | * center element in the range. These elements will be used for 2923 | * pivot selection as described below. The choice for spacing 2924 | * these elements was empirically determined to work well on 2925 | * a wide variety of inputs. 2926 | */ 2927 | int e3 = (left + right) >>> 1; // The midpoint 2928 | int e2 = e3 - seventh; 2929 | int e1 = e2 - seventh; 2930 | int e4 = e3 + seventh; 2931 | int e5 = e4 + seventh; 2932 | 2933 | // Sort these elements using insertion sort 2934 | if (a[e2] < a[e1]) { double t = a[e2]; a[e2] = a[e1]; a[e1] = t; } 2935 | 2936 | if (a[e3] < a[e2]) { double t = a[e3]; a[e3] = a[e2]; a[e2] = t; 2937 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 2938 | } 2939 | if (a[e4] < a[e3]) { double t = a[e4]; a[e4] = a[e3]; a[e3] = t; 2940 | if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; 2941 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 2942 | } 2943 | } 2944 | if (a[e5] < a[e4]) { double t = a[e5]; a[e5] = a[e4]; a[e4] = t; 2945 | if (t < a[e3]) { a[e4] = a[e3]; a[e3] = t; 2946 | if (t < a[e2]) { a[e3] = a[e2]; a[e2] = t; 2947 | if (t < a[e1]) { a[e2] = a[e1]; a[e1] = t; } 2948 | } 2949 | } 2950 | } 2951 | 2952 | // Pointers 2953 | int less = left; // The index of the first element of center part 2954 | int great = right; // The index before the first element of right part 2955 | 2956 | if (a[e1] != a[e2] && a[e2] != a[e3] && a[e3] != a[e4] && a[e4] != a[e5]) { 2957 | /* 2958 | * Use the second and fourth of the five sorted elements as pivots. 2959 | * These values are inexpensive approximations of the first and 2960 | * second terciles of the array. Note that pivot1 <= pivot2. 2961 | */ 2962 | double pivot1 = a[e2]; 2963 | double pivot2 = a[e4]; 2964 | 2965 | /* 2966 | * The first and the last elements to be sorted are moved to the 2967 | * locations formerly occupied by the pivots. When partitioning 2968 | * is complete, the pivots are swapped back into their final 2969 | * positions, and excluded from subsequent sorting. 2970 | */ 2971 | a[e2] = a[left]; 2972 | a[e4] = a[right]; 2973 | 2974 | /* 2975 | * Skip elements, which are less or greater than pivot values. 2976 | */ 2977 | while (a[++less] < pivot1); 2978 | while (a[--great] > pivot2); 2979 | 2980 | /* 2981 | * Partitioning: 2982 | * 2983 | * left part center part right part 2984 | * +--------------------------------------------------------------+ 2985 | * | < pivot1 | pivot1 <= && <= pivot2 | ? | > pivot2 | 2986 | * +--------------------------------------------------------------+ 2987 | * ^ ^ ^ 2988 | * | | | 2989 | * less k great 2990 | * 2991 | * Invariants: 2992 | * 2993 | * all in (left, less) < pivot1 2994 | * pivot1 <= all in [less, k) <= pivot2 2995 | * all in (great, right) > pivot2 2996 | * 2997 | * Pointer k is the first index of ?-part. 2998 | */ 2999 | outer: 3000 | for (int k = less - 1; ++k <= great; ) { 3001 | double ak = a[k]; 3002 | if (ak < pivot1) { // Move a[k] to left part 3003 | a[k] = a[less]; 3004 | /* 3005 | * Here and below we use "a[i] = b; i++;" instead 3006 | * of "a[i++] = b;" due to performance issue. 3007 | */ 3008 | a[less] = ak; 3009 | ++less; 3010 | } else if (ak > pivot2) { // Move a[k] to right part 3011 | while (a[great] > pivot2) { 3012 | if (great-- == k) { 3013 | break outer; 3014 | } 3015 | } 3016 | if (a[great] < pivot1) { // a[great] <= pivot2 3017 | a[k] = a[less]; 3018 | a[less] = a[great]; 3019 | ++less; 3020 | } else { // pivot1 <= a[great] <= pivot2 3021 | a[k] = a[great]; 3022 | } 3023 | /* 3024 | * Here and below we use "a[i] = b; i--;" instead 3025 | * of "a[i--] = b;" due to performance issue. 3026 | */ 3027 | a[great] = ak; 3028 | --great; 3029 | } 3030 | } 3031 | 3032 | // Swap pivots into their final positions 3033 | a[left] = a[less - 1]; a[less - 1] = pivot1; 3034 | a[right] = a[great + 1]; a[great + 1] = pivot2; 3035 | 3036 | // Sort left and right parts recursively, excluding known pivots 3037 | sort(a, left, less - 2, leftmost); 3038 | sort(a, great + 2, right, false); 3039 | 3040 | /* 3041 | * If center part is too large (comprises > 4/7 of the array), 3042 | * swap internal pivot values to ends. 3043 | */ 3044 | if (less < e1 && e5 < great) { 3045 | /* 3046 | * Skip elements, which are equal to pivot values. 3047 | */ 3048 | while (a[less] == pivot1) { 3049 | ++less; 3050 | } 3051 | 3052 | while (a[great] == pivot2) { 3053 | --great; 3054 | } 3055 | 3056 | /* 3057 | * Partitioning: 3058 | * 3059 | * left part center part right part 3060 | * +----------------------------------------------------------+ 3061 | * | == pivot1 | pivot1 < && < pivot2 | ? | == pivot2 | 3062 | * +----------------------------------------------------------+ 3063 | * ^ ^ ^ 3064 | * | | | 3065 | * less k great 3066 | * 3067 | * Invariants: 3068 | * 3069 | * all in (*, less) == pivot1 3070 | * pivot1 < all in [less, k) < pivot2 3071 | * all in (great, *) == pivot2 3072 | * 3073 | * Pointer k is the first index of ?-part. 3074 | */ 3075 | outer: 3076 | for (int k = less - 1; ++k <= great; ) { 3077 | double ak = a[k]; 3078 | if (ak == pivot1) { // Move a[k] to left part 3079 | a[k] = a[less]; 3080 | a[less] = ak; 3081 | ++less; 3082 | } else if (ak == pivot2) { // Move a[k] to right part 3083 | while (a[great] == pivot2) { 3084 | if (great-- == k) { 3085 | break outer; 3086 | } 3087 | } 3088 | if (a[great] == pivot1) { // a[great] < pivot2 3089 | a[k] = a[less]; 3090 | /* 3091 | * Even though a[great] equals to pivot1, the 3092 | * assignment a[less] = pivot1 may be incorrect, 3093 | * if a[great] and pivot1 are floating-point zeros 3094 | * of different signs. Therefore in float and 3095 | * double sorting methods we have to use more 3096 | * accurate assignment a[less] = a[great]. 3097 | */ 3098 | a[less] = a[great]; 3099 | ++less; 3100 | } else { // pivot1 < a[great] < pivot2 3101 | a[k] = a[great]; 3102 | } 3103 | a[great] = ak; 3104 | --great; 3105 | } 3106 | } 3107 | } 3108 | 3109 | // Sort center part recursively 3110 | sort(a, less, great, false); 3111 | 3112 | } else { // Partitioning with one pivot 3113 | /* 3114 | * Use the third of the five sorted elements as pivot. 3115 | * This value is inexpensive approximation of the median. 3116 | */ 3117 | double pivot = a[e3]; 3118 | 3119 | /* 3120 | * Partitioning degenerates to the traditional 3-way 3121 | * (or "Dutch National Flag") schema: 3122 | * 3123 | * left part center part right part 3124 | * +-------------------------------------------------+ 3125 | * | < pivot | == pivot | ? | > pivot | 3126 | * +-------------------------------------------------+ 3127 | * ^ ^ ^ 3128 | * | | | 3129 | * less k great 3130 | * 3131 | * Invariants: 3132 | * 3133 | * all in (left, less) < pivot 3134 | * all in [less, k) == pivot 3135 | * all in (great, right) > pivot 3136 | * 3137 | * Pointer k is the first index of ?-part. 3138 | */ 3139 | for (int k = less; k <= great; ++k) { 3140 | if (a[k] == pivot) { 3141 | continue; 3142 | } 3143 | double ak = a[k]; 3144 | if (ak < pivot) { // Move a[k] to left part 3145 | a[k] = a[less]; 3146 | a[less] = ak; 3147 | ++less; 3148 | } else { // a[k] > pivot - Move a[k] to right part 3149 | while (a[great] > pivot) { 3150 | --great; 3151 | } 3152 | if (a[great] < pivot) { // a[great] <= pivot 3153 | a[k] = a[less]; 3154 | a[less] = a[great]; 3155 | ++less; 3156 | } else { // a[great] == pivot 3157 | /* 3158 | * Even though a[great] equals to pivot, the 3159 | * assignment a[k] = pivot may be incorrect, 3160 | * if a[great] and pivot are floating-point 3161 | * zeros of different signs. Therefore in float 3162 | * and double sorting methods we have to use 3163 | * more accurate assignment a[k] = a[great]. 3164 | */ 3165 | a[k] = a[great]; 3166 | } 3167 | a[great] = ak; 3168 | --great; 3169 | } 3170 | } 3171 | 3172 | /* 3173 | * Sort left and right parts recursively. 3174 | * All elements from center part are equal 3175 | * and, therefore, already sorted. 3176 | */ 3177 | sort(a, left, less - 1, leftmost); 3178 | sort(a, great + 1, right, false); 3179 | } 3180 | } 3181 | } 3182 | -------------------------------------------------------------------------------- /src/Test/RadixSortTest.java: -------------------------------------------------------------------------------- 1 | package Test; 2 | 3 | import static org.junit.jupiter.api.Assertions.*; 4 | 5 | import java.util.Arrays; 6 | import java.util.Random; 7 | 8 | import org.junit.jupiter.api.Test; 9 | 10 | import com.mashibing.RadixSort; 11 | 12 | class RadixSortTest { 13 | 14 | int[] generateRandomArray() { 15 | Random r = new Random(); 16 | 17 | int[] arr = new int[10000]; 18 | 19 | for (int i = 0; i < arr.length; i++) 20 | arr[i] = r.nextInt(1000); 21 | 22 | return arr; 23 | } 24 | 25 | 26 | @Test 27 | void testSort() { 28 | int[] a = generateRandomArray(); 29 | int[] result = RadixSort.sort(a); 30 | Arrays.sort(a); 31 | boolean same = true; 32 | 33 | for (int i = 0; i < a.length; i++) { 34 | if(result[i] != a[i]) same = false; 35 | } 36 | 37 | assertEquals(true, same); 38 | 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/com/mashibing/BinarySearch.java: -------------------------------------------------------------------------------- 1 | package com.mashibing; 2 | 3 | public class BinarySearch { 4 | public static void main(String[] args) { 5 | int[] a = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 6 | 7 | int num = 100; 8 | int pos = -1; 9 | 10 | for (int start = 0, end = a.length - 1; start <= end;) { 11 | int middle = (start + end) / 2; 12 | if (a[middle] == num) { 13 | pos = middle; 14 | break; 15 | } else if (a[middle] < num) { 16 | start = middle+1; 17 | } else { 18 | end = middle-1; 19 | } 20 | } 21 | 22 | System.out.println(pos); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/com/mashibing/BubbleSort.java: -------------------------------------------------------------------------------- 1 | package com.mashibing; 2 | 3 | public class BubbleSort { 4 | public static void main(String[] args) { 5 | int[] a = { 9, 3, 1, 4, 6, 8, 7, 5, 2}; 6 | sort(a); 7 | print(a); 8 | } 9 | 10 | static void sort(int[] a) { 11 | for(int i=a.length-1; i>0; i--) 12 | findMax(a, i); 13 | } 14 | 15 | static void findMax(int[] a, int n) { 16 | for(int j=0; j a[j+1]) swap(a, j, j+1); 18 | } 19 | } 20 | 21 | static void swap(int[] a, int i, int j) { 22 | int temp = a[i]; 23 | a[i] = a[j]; 24 | a[j] = temp; 25 | } 26 | 27 | static void print(int[] arr) { 28 | for(int i=0; i 0) result[j++] = i; 30 | // } 31 | 32 | for(int i=1; i=0; i--) { 39 | result[--count[arr[i]]] = arr[i]; 40 | } 41 | 42 | return result; 43 | } 44 | 45 | 46 | static void swap(int[] a, int i, int j) { 47 | int temp = a[i]; 48 | a[i] = a[j]; 49 | a[j] = temp; 50 | } 51 | 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/com/mashibing/DataChecker.java: -------------------------------------------------------------------------------- 1 | package com.mashibing; 2 | 3 | import java.util.Arrays; 4 | import java.util.Random; 5 | 6 | public class DataChecker { 7 | 8 | static int[] generateRandomArray() { 9 | Random r = new Random(); 10 | 11 | int[] arr = new int[10000]; 12 | 13 | for (int i = 0; i < arr.length; i++) 14 | arr[i] = r.nextInt(10000); 15 | 16 | return arr; 17 | } 18 | 19 | static void check() { 20 | boolean same = true; 21 | for(int times = 0; times < 1000; times++) { 22 | int[] arr = generateRandomArray(); 23 | int[] arr2 = new int[arr.length]; 24 | System.arraycopy(arr, 0, arr2, 0, arr.length); 25 | 26 | Arrays.sort(arr); 27 | //SelectionSort.sort(arr2); 28 | //BubbleSort.sort(arr2); 29 | //InsertionSort.sort(arr2); 30 | //ShellSort.sort(arr2); 31 | //MergeSort.sort(arr2, 0, arr2.length-1); 32 | QuickSort.sort(arr2, 0, arr2.length-1); 33 | 34 | 35 | for (int i = 0; i < arr2.length; i++) { 36 | if(arr[i] != arr2[i]) same = false; 37 | } 38 | } 39 | System.out.println(same == true ? "right" : "wrong"); 40 | 41 | } 42 | 43 | public static void main(String[] args) { 44 | check(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/com/mashibing/InsertionSort.java: -------------------------------------------------------------------------------- 1 | package com.mashibing; 2 | 3 | public class InsertionSort { 4 | public static void main(String[] args) { 5 | int[] a = { 9, 3, 1, 4, 6, 8, 7, 5, 2 }; 6 | sort(a); 7 | print(a); 8 | } 9 | 10 | static void sort(int[] a) { 11 | for(int i=1; i0 && a[j] < a[j-1]; j--) { 13 | //if(a[j] < a[j-1]) { 14 | swap(a, j, j-1); 15 | //} 16 | } 17 | } 18 | } 19 | 20 | static void swap(int[] a, int i, int j) { 21 | int temp = a[i]; 22 | a[i] = a[j]; 23 | a[j] = temp; 24 | } 25 | 26 | static void print(int[] arr) { 27 | for (int i = 0; i < arr.length; i++) { 28 | System.out.print(arr[i] + " "); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/com/mashibing/MergeSort.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bjmashibing/Algorithm/145d65d8e7a8fb6ad6877c92a9ecb328e935c2ea/src/com/mashibing/MergeSort.java -------------------------------------------------------------------------------- /src/com/mashibing/QuickSort.java: -------------------------------------------------------------------------------- 1 | package com.mashibing; 2 | 3 | public class QuickSort { 4 | public static void main(String[] args) { 5 | int[] arr = {4, 6}; 6 | sort(arr, 0, arr.length-1); 7 | 8 | print(arr); 9 | 10 | } 11 | 12 | public static void sort(int[] arr, int leftBound, int rightBound) { 13 | if(leftBound >= rightBound) return; 14 | int mid = partition(arr, leftBound, rightBound); 15 | sort(arr, leftBound, mid-1); 16 | sort(arr, mid+1, rightBound); 17 | } 18 | 19 | static int partition(int[] arr, int leftBound, int rightBound) { 20 | int pivot = arr[rightBound]; 21 | int left = leftBound; 22 | int right = rightBound - 1; 23 | 24 | while(left <= right) { 25 | while(left <= right && arr[left] <= pivot) left ++; 26 | while(left <= right && arr[right] > pivot) right --; 27 | 28 | //System.out.println("before swap: left->" + left + " right->" + right); 29 | 30 | if(left < right) swap(arr, left, right); 31 | 32 | // System.out.print("--"); 33 | // print( arr); 34 | // System.out.println(); 35 | 36 | } 37 | 38 | swap(arr, left, rightBound); 39 | 40 | return left; 41 | } 42 | 43 | static void swap(int[] arr, int i, int j) { 44 | int temp = arr[i]; 45 | arr[i] = arr[j]; 46 | arr[j] = temp; 47 | } 48 | 49 | static void print(int[] arr) { 50 | for(int i=0; i 0; gap = (gap-1)/3) { 22 | 23 | for(int i=gap; igap-1; j-=gap) { 25 | if(arr[j] < arr[j-gap]) { 26 | swap(arr, j, j-gap); 27 | } 28 | } 29 | } 30 | } 31 | 32 | } 33 | 34 | static void swap(int[] arr, int i, int j) { 35 | int temp = arr[i]; 36 | arr[i] = arr[j]; 37 | arr[j] = temp; 38 | } 39 | 40 | static void print(int[] arr) { 41 | for(int i=0; i=0; i--) { 28 | arr2[--count[arr[i]]] = arr[i]; 29 | } 30 | 31 | /*for(int i=0, j=0; i 0) arr2[j++] = i; 34 | }*/ 35 | 36 | System.out.println(Arrays.toString(arr2)); 37 | } 38 | } 39 | 40 | class Cat { 41 | int id; 42 | String name; 43 | Cat(int id, String name) { 44 | this.id = id; 45 | this.name = name; 46 | } 47 | @Override 48 | public String toString() { 49 | return this.id + " " + this.name; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/com/mashibing/T_0001_BigO.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bjmashibing/Algorithm/145d65d8e7a8fb6ad6877c92a9ecb328e935c2ea/src/com/mashibing/T_0001_BigO.java -------------------------------------------------------------------------------- /src/com/mashibing/linkedlist/BiDirLL.java: -------------------------------------------------------------------------------- 1 | package com.mashibing.linkedlist; 2 | 3 | public class BiDirLL { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/com/mashibing/linkedlist/BiDirLoopLL.java: -------------------------------------------------------------------------------- 1 | package com.mashibing.linkedlist; 2 | 3 | public class BiDirLoopLL { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/com/mashibing/linkedlist/Node.java: -------------------------------------------------------------------------------- 1 | package com.mashibing.linkedlist; 2 | 3 | public class Node { 4 | int value; 5 | Node next = null; 6 | 7 | Node(int value) { 8 | this.value = value; 9 | } 10 | 11 | @Override 12 | public String toString() { 13 | return " "+value+ " "; 14 | } 15 | 16 | public static void main(String[] args) { 17 | Node n1 = new Node(1); 18 | Node n2 = new Node(2); 19 | Node n3 = new Node(3); 20 | n1.next = n2; 21 | n2.next = n3; 22 | 23 | Node n = n1; 24 | while(n != null) { 25 | System.out.print(n); 26 | n = n.next; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/com/mashibing/linkedlist/OneDirLoopLL.java: -------------------------------------------------------------------------------- 1 | package com.mashibing.linkedlist; 2 | 3 | public class OneDirLoopLL { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /src/com/mashibing/linkedlist/SimpleLL.java: -------------------------------------------------------------------------------- 1 | package com.mashibing.linkedlist; 2 | 3 | /** 4 | * simple linked list, one direction 5 | * @author www.mashibing.com 6 | * 7 | */ 8 | public class SimpleLL { 9 | //add insert delete loop 10 | } 11 | -------------------------------------------------------------------------------- /src/com/mashibing/search/BinarySearch.java: -------------------------------------------------------------------------------- 1 | package com.mashibing.search; 2 | 3 | 4 | public class BinarySearch { 5 | } 6 | --------------------------------------------------------------------------------