Question: Write a program to compute the exact value of the number of array accesses used by top-down mergesort and by bottom-up mergesort. Use your program to plot the values for N from 1 to 512, and to compare the exact values with the upper bound 6N lg N.

Answer:
// Exercise6.java
package chapter2.section2;

import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by Rene Argento on 11/02/17.
 */
// Thanks to ajfg93 (https://github.com/ajfg93) for correcting the array access count.
// https://github.com/reneargento/algorithms-sedgewick-wayne/issues/12
public class Exercise6 {

    private enum SortType {
        TOP_DOWN_MERGESORT, BOTTOM_UP_MERGESORT;
    }

    private static int numberOfArrayAccesses;

    public static void main(String[] args) {

        int initialArraySize = 1;
        int numberOfExperiments = 512;

        Map<Integer, Comparable[]> allInputArrays = generateAllArrays(initialArraySize, numberOfExperiments);

        StdOut.printf("%6s %15s %11s\n", "N", "Array Accesses", "Upper Bound");
        StdOut.println();

        StdOut.printf("Top-Down MergeSort");
        StdOut.println();
        doExperiments(SortType.TOP_DOWN_MERGESORT, 1, 512, allInputArrays);

        StdOut.println();
        StdOut.printf("Bottom-Up MergeSort");
        StdOut.println();
        doExperiments(SortType.BOTTOM_UP_MERGESORT, 1, 512, allInputArrays);
    }

    private static void doExperiments(SortType sortType, int arrayLength, int numberOfExperiments,
                                      Map<Integer, Comparable[]> allInputArrays) {

        for (int i = 0; i < numberOfExperiments; i++) {

            numberOfArrayAccesses = 0;

            Comparable[] originalArray = allInputArrays.get(i);
            Comparable[] array = new Comparable[originalArray.length];
            System.arraycopy(originalArray, 0, array, 0, originalArray.length);

            if (sortType == SortType.TOP_DOWN_MERGESORT) {
                topDownMergeSort(array);
            } else if (sortType == SortType.BOTTOM_UP_MERGESORT) {
                bottomUpMergeSort(array);
            }

            printExperiment(arrayLength);

            arrayLength++;
        }
    }

    private static Map<Integer, Comparable[]> generateAllArrays(int initialArraySize, int numberOfExperiments) {

        Map<Integer, Comparable[]> allArrays = new HashMap<>();

        int arraySize = initialArraySize;

        for (int i = 0; i < numberOfExperiments; i++) {
            Comparable[] array = generateRandomArray(arraySize);
            allArrays.put(i, array);

            arraySize++;
        }

        return allArrays;
    }

    private static Comparable[] generateRandomArray(int arrayLength) {
        Comparable[] array = new Comparable[arrayLength];

        for (int i = 0; i < arrayLength; i++) {
            array[i] = StdRandom.uniform();
        }

        return array;
    }

    private static void topDownMergeSort(Comparable[] array) {
        Comparable[] aux = new Comparable[array.length];

        topDownMergeSort(array, aux, 0, array.length - 1);
    }

    private static void topDownMergeSort(Comparable[] array, Comparable[] aux, int low, int high) {

        if (high <= low) {
            return;
        }

        int middle = low + (high - low) / 2;

        topDownMergeSort(array, aux, low, middle);
        topDownMergeSort(array, aux, middle + 1, high);

        merge(array, aux, low, middle, high);
    }

    private static void bottomUpMergeSort(Comparable[] array) {

        Comparable[] aux = new Comparable[array.length];

        for (int size = 1; size < array.length; size = size + size) {

            for (int low = 0; low + size < array.length; low += size + size) {
                int high = Math.min(low + size + size - 1, array.length - 1);

                merge(array, aux, low, low + size - 1, high);
            }
        }
    }

    @SuppressWarnings("unchecked")
    private static void merge(Comparable[] array, Comparable[] aux, int low, int middle, int high) {
        for (int i = low; i <= high; i++) {
            aux[i] = array[i];

            numberOfArrayAccesses += 2;
        }

        int indexLeft = low;
        int indexRight = middle + 1;
        int arrayIndex = low;

        while (indexLeft <= middle && indexRight <= high) {
            if (aux[indexLeft].compareTo(aux[indexRight]) <= 0) {
                array[arrayIndex] = aux[indexLeft];
                indexLeft++;
            } else {
                array[arrayIndex] = aux[indexRight];
                indexRight++;
            }

            arrayIndex++;
            numberOfArrayAccesses += 4;
        }

        while (indexLeft <= middle) {
            array[arrayIndex] = aux[indexLeft];

            indexLeft++;
            arrayIndex++;

            numberOfArrayAccesses += 2;
        }
    }

    private static void printExperiment(int arrayLength) {
        double upperBound = 6 * arrayLength * (Math.log10(arrayLength) / Math.log10(2));

        StdOut.printf("%6d %15d %11.0f\n", arrayLength, numberOfArrayAccesses, upperBound);
    }
}

Additional notes/results:
2.2.6

     N  Array Accesses Upper Bound

Top-Down MergeSort
     1               0           0
     2               8          12
     3              22          29
     4              38          48
     5              56          70
     6              80          93
     7             100         118
     8             116         144
     9             138         171
    10             174         199
    11             192         228
    12             230         258
    13             248         289
    14             270         320
    15             304         352
    16             336         384
    17             372         417
    18             380         450
    19             430         484
    20             452         519
    21             484         553
    22             532         589
    23             560         624
    24             594         660
    25             622         697
    26             650         733
    27             694         770
    28             720         808
    29             746         845
    30             796         883
    31             814         921
    32             852         960
    33             888         999
    34             946        1038
    35             972        1077
    36            1012        1117
    37            1036        1156
    38            1052        1197
    39            1108        1237
    40            1164        1277
    41            1164        1318
    42            1238        1359
    43            1278        1400
    44            1308        1441
    45            1368        1483
    46            1412        1525
    47            1402        1566
    48            1472        1608
    49            1492        1651
    50            1546        1693
    51            1556        1736
    52            1632        1779
    53            1640        1821
    54            1678        1865
    55            1738        1908
    56            1770        1951
    57            1814        1995
    58            1846        2039
    59            1880        2082
    60            1926        2126
    61            1950        2171
    62            1994        2215
    63            2034        2259
    64            2092        2304
    65            2122        2349
    66            2150        2394
    67            2184        2439
    68            2248        2484
    69            2262        2529
    70            2344        2574
    71            2374        2620
    72            2432        2665
    73            2474        2711
    74            2498        2757
    75            2564        2803
    76            2590        2849
    77            2662        2895
    78            2704        2942
    79            2740        2988
    80            2768        3035
    81            2856        3081
    82            2872        3128
    83            2912        3175
    84            2968        3222
    85            2976        3269
    86            3020        3316
    87            3112        3363
    88            3122        3411
    89            3174        3458
    90            3194        3506
    91            3248        3553
    92            3342        3601
    93            3362        3649
    94            3398        3697
    95            3426        3745
    96            3508        3793
    97            3532        3841
    98            3598        3889
    99            3618        3938
   100            3638        3986
   101            3738        4035
   102            3768        4084
   103            3824        4132
   104            3836        4181
   105            3902        4230
   106            3900        4279
   107            3966        4328
   108            4008        4377
   109            4058        4426
   110            4104        4476
   111            4152        4525
   112            4180        4575
   113            4226        4624
   114            4272        4674
   115            4312        4723
   116            4318        4773
   117            4452        4823
   118            4480        4873
   119            4450        4923
   120            4552        4973
   121            4604        5023
   122            4624        5073
   123            4712        5124
   124            4752        5174
   125            4738        5224
   126            4810        5275
   127            4816        5325
   128            4848        5376
   129            4928        5427
   130            4960        5477
   131            5062        5528
   132            5152        5579
   133            5156        5630
   134            5196        5681
   135            5240        5732
   136            5318        5783
   137            5338        5835
   138            5390        5886
   139            5466        5937
   140            5444        5989
   141            5536        6040
   142            5624        6092
   143            5680        6143
   144            5682        6195
   145            5758        6247
   146            5838        6298
   147            5886        6350
   148            5918        6402
   149            5956        6454
   150            6002        6506
   151            6042        6558
   152            6062        6610
   153            6178        6662
   154            6188        6715
   155            6212        6767
   156            6260        6819
   157            6388        6872
   158            6446        6924
   159            6482        6976
   160            6526        7029
   161            6586        7082
   162            6630        7134
   163            6650        7187
   164            6682        7240
   165            6766        7293
   166            6846        7346
   167            6902        7398
   168            6966        7451
   169            6954        7504
   170            7028        7558
   171            7008        7611
   172            7118        7664
   173            7166        7717
   174            7226        7770
   175            7262        7824
   176            7304        7877
   177            7328        7931
   178            7396        7984
   179            7464        8038
   180            7508        8091
   181            7568        8145
   182            7598        8199
   183            7694        8252
   184            7684        8306
   185            7772        8360
   186            7758        8414
   187            7882        8468
   188            7910        8522
   189            7924        8576
   190            8012        8630
   191            8026        8684
   192            8140        8738
   193            8176        8792
   194            8248        8846
   195            8270        8901
   196            8318        8955
   197            8374        9009
   198            8406        9064
   199            8466        9118
   200            8548        9173
   201            8528        9227
   202            8598        9282
   203            8642        9336
   204            8772        9391
   205            8786        9446
   206            8800        9501
   207            8862        9555
   208            8946        9610
   209            8986        9665
   210            8964        9720
   211            9094        9775
   212            9128        9830
   213            9114        9885
   214            9170        9940
   215            9294        9995
   216            9308       10050
   217            9368       10106
   218            9394       10161
   219            9484       10216
   220            9528       10271
   221            9574       10327
   222            9666       10382
   223            9614       10438
   224            9706       10493
   225            9778       10549
   226            9860       10604
   227            9890       10660
   228            9980       10715
   229           10036       10771
   230            9982       10827
   231           10086       10883
   232           10128       10938
   233           10136       10994
   234           10218       11050
   235           10292       11106
   236           10328       11162
   237           10368       11218
   238           10416       11274
   239           10474       11330
   240           10478       11386
   241           10614       11442
   242           10610       11498
   243           10636       11554
   244           10686       11611
   245           10856       11667
   246           10888       11723
   247           10890       11779
   248           10882       11836
   249           10952       11892
   250           11010       11949
   251           11094       12005
   252           11110       12062
   253           11128       12118
   254           11260       12175
   255           11260       12231
   256           11310       12288
   257           11388       12345
   258           11470       12401
   259           11456       12458
   260           11488       12515
   261           11640       12572
   262           11672       12629
   263           11722       12685
   264           11722       12742
   265           11880       12799
   266           11876       12856
   267           11918       12913
   268           12036       12970
   269           12094       13027
   270           12094       13084
   271           12150       13142
   272           12228       13199
   273           12308       13256
   274           12366       13313
   275           12398       13370
   276           12448       13428
   277           12500       13485
   278           12524       13542
   279           12686       13600
   280           12684       13657
   281           12754       13715
   282           12804       13772
   283           12882       13830
   284           12922       13887
   285           13016       13945
   286           13062       14002
   287           13066       14060
   288           13110       14118
   289           13194       14175
   290           13298       14233
   291           13328       14291
   292           13480       14349
   293           13476       14406
   294           13446       14464
   295           13596       14522
   296           13628       14580
   297           13628       14638
   298           13656       14696
   299           13754       14754
   300           13832       14812
   301           13852       14870
   302           13896       14928
   303           14020       14986
   304           14010       15044
   305           14090       15102
   306           14196       15161
   307           14230       15219
   308           14288       15277
   309           14368       15335
   310           14336       15394
   311           14394       15452
   312           14464       15510
   313           14532       15569
   314           14612       15627
   315           14626       15686
   316           14704       15744
   317           14762       15802
   318           14834       15861
   319           14854       15920
   320           14974       15978
   321           15002       16037
   322           14986       16095
   323           15142       16154
   324           15148       16213
   325           15168       16271
   326           15250       16330
   327           15316       16389
   328           15402       16448
   329           15494       16506
   330           15454       16565
   331           15546       16624
   332           15632       16683
   333           15674       16742
   334           15774       16801
   335           15746       16860
   336           15854       16919
   337           15922       16978
   338           16032       17037
   339           16016       17096
   340           16104       17155
   341           16112       17214
   342           16188       17273
   343           16288       17333
   344           16274       17392
   345           16328       17451
   346           16370       17510
   347           16458       17570
   348           16544       17629
   349           16606       17688
   350           16666       17748
   351           16758       17807
   352           16730       17866
   353           16744       17926
   354           16848       17985
   355           16930       18045
   356           16980       18104
   357           16986       18164
   358           17092       18223
   359           17110       18283
   360           17202       18342
   361           17204       18402
   362           17276       18462
   363           17350       18521
   364           17358       18581
   365           17444       18641
   366           17472       18700
   367           17570       18760
   368           17678       18820
   369           17706       18880
   370           17758       18940
   371           17814       19000
   372           17882       19059
   373           17926       19119
   374           17994       19179
   375           18040       19239
   376           18110       19299
   377           18194       19359
   378           18166       19419
   379           18248       19479
   380           18318       19539
   381           18300       19599
   382           18424       19659
   383           18510       19720
   384           18530       19780
   385           18644       19840
   386           18640       19900
   387           18714       19960
   388           18794       20021
   389           18726       20081
   390           18806       20141
   391           18966       20201
   392           18970       20262
   393           19102       20322
   394           19106       20383
   395           19154       20443
   396           19166       20503
   397           19394       20564
   398           19296       20624
   399           19294       20685
   400           19408       20745
   401           19318       20806
   402           19522       20866
   403           19666       20927
   404           19698       20988
   405           19716       21048
   406           19714       21109
   407           19868       21169
   408           19958       21230
   409           19878       21291
   410           20006       21352
   411           20024       21412
   412           20030       21473
   413           20168       21534
   414           20290       21595
   415           20402       21655
   416           20328       21716
   417           20380       21777
   418           20430       21838
   419           20520       21899
   420           20478       21960
   421           20630       22021
   422           20672       22082
   423           20724       22143
   424           20780       22204
   425           20856       22265
   426           20928       22326
   427           20994       22387
   428           21032       22448
   429           21028       22509
   430           21150       22570
   431           21210       22631
   432           21228       22693
   433           21388       22754
   434           21336       22815
   435           21432       22876
   436           21406       22938
   437           21486       22999
   438           21532       23060
   439           21648       23121
   440           21732       23183
   441           21732       23244
   442           21820       23306
   443           21904       23367
   444           21946       23428
   445           22018       23490
   446           22040       23551
   447           22106       23613
   448           22136       23674
   449           22218       23736
   450           22200       23797
   451           22224       23859
   452           22414       23920
   453           22364       23982
   454           22472       24044
   455           22438       24105
   456           22580       24167
   457           22706       24228
   458           22754       24290
   459           22748       24352
   460           22794       24414
   461           22894       24475
   462           22848       24537
   463           22982       24599
   464           22982       24661
   465           23116       24722
   466           23198       24784
   467           23214       24846
   468           23252       24908
   469           23314       24970
   470           23426       25032
   471           23414       25094
   472           23466       25156
   473           23560       25218
   474           23620       25280
   475           23702       25342
   476           23812       25404
   477           23762       25466
   478           23812       25528
   479           23894       25590
   480           23954       25652
   481           23980       25714
   482           23962       25776
   483           24070       25838
   484           24134       25900
   485           24174       25963
   486           24174       26025
   487           24268       26087
   488           24372       26149
   489           24440       26211
   490           24508       26274
   491           24474       26336
   492           24644       26398
   493           24752       26461
   494           24778       26523
   495           24772       26585
   496           24830       26648
   497           24746       26710
   498           24922       26772
   499           24994       26835
   500           25066       26897
   501           25156       26960
   502           25154       27022
   503           25194       27085
   504           25224       27147
   505           25366       27210
   506           25292       27272
   507           25442       27335
   508           25462       27398
   509           25506       27460
   510           25660       27523
   511           25576       27585
   512           25710       27648

Bottom-Up MergeSort
     1               0           0
     2               8          12
     3              22          29
     4              38          48
     5              60          70
     6              84          93
     7             100         118
     8             116         144
     9             156         171
    10             188         199
    11             206         228
    12             228         258
    13             254         289
    14             270         320
    15             304         352
    16             336         384
    17             408         417
    18             434         450
    19             478         484
    20             468         519
    21             510         553
    22             548         589
    23             562         624
    24             588         660
    25             644         697
    26             658         733
    27             694         770
    28             716         808
    29             748         845
    30             808         883
    31             814         921
    32             852         960
    33             986         999
    34            1034        1038
    35            1082        1077
    36            1100        1117
    37            1108        1156
    38            1168        1197
    39            1176        1237
    40            1198        1277
    41            1252        1318
    42            1242        1359
    43            1314        1400
    44            1330        1441
    45            1378        1483
    46            1398        1525
    47            1420        1566
    48            1478        1608
    49            1574        1651
    50            1588        1693
    51            1586        1736
    52            1634        1779
    53            1660        1821
    54            1702        1865
    55            1752        1908
    56            1780        1951
    57            1792        1995
    58            1856        2039
    59            1898        2082
    60            1914        2126
    61            1946        2171
    62            1988        2215
    63            2034        2259
    64            2092        2304
    65            2390        2349
    66            2430        2394
    67            2464        2439
    68            2530        2484
    69            2510        2529
    70            2566        2574
    71            2608        2620
    72            2624        2665
    73            2632        2711
    74            2704        2757
    75            2728        2803
    76            2744        2849
    77            2750        2895
    78            2774        2942
    79            2828        2988
    80            2874        3035
    81            2982        3081
    82            2990        3128
    83            3036        3175
    84            3060        3222
    85            3082        3269
    86            3076        3316
    87            3162        3363
    88            3168        3411
    89            3258        3458
    90            3250        3506
    91            3304        3553
    92            3350        3601
    93            3354        3649
    94            3422        3697
    95            3406        3745
    96            3492        3793
    97            3636        3841
    98            3700        3889
    99            3754        3938
   100            3738        3986
   101            3810        4035
   102            3842        4084
   103            3850        4132
   104            3878        4181
   105            3934        4230
   106            3968        4279
   107            3968        4328
   108            4054        4377
   109            4106        4426
   110            4090        4476
   111            4142        4525
   112            4184        4575
   113            4288        4624
   114            4306        4674
   115            4366        4723
   116            4348        4773
   117            4450        4823
   118            4456        4873
   119            4478        4923
   120            4526        4973
   121            4562        5023
   122            4638        5073
   123            4704        5124
   124            4744        5174
   125            4748        5224
   126            4820        5275
   127            4816        5325
   128            4848        5376
   129            5544        5427
   130            5606        5477
   131            5620        5528
   132            5668        5579
   133            5762        5630
   134            5728        5681
   135            5756        5732
   136            5776        5783
   137            5810        5835
   138            5852        5886
   139            5910        5937
   140            5940        5989
   141            5990        6040
   142            5980        6092
   143            6032        6143
   144            6050        6195
   145            6176        6247
   146            6234        6298
   147            6210        6350
   148            6212        6402
   149            6300        6454
   150            6300        6506
   151            6318        6558
   152            6364        6610
   153            6478        6662
   154            6488        6715
   155            6564        6767
   156            6552        6819
   157            6620        6872
   158            6614        6924
   159            6698        6976
   160            6708        7029
   161            6844        7082
   162            6902        7134
   163            6936        7187
   164            6930        7240
   165            6970        7293
   166            7050        7346
   167            7038        7398
   168            7062        7451
   169            7190        7504
   170            7208        7558
   171            7176        7611
   172            7248        7664
   173            7280        7717
   174            7290        7770
   175            7368        7824
   176            7402        7877
   177            7500        7931
   178            7526        7984
   179            7516        8038
   180            7568        8091
   181            7582        8145
   182            7652        8199
   183            7736        8252
   184            7712        8306
   185            7752        8360
   186            7806        8414
   187            7926        8468
   188            7972        8522
   189            7982        8576
   190            8054        8630
   191            8068        8684
   192            8122        8738
   193            8468        8792
   194            8410        8846
   195            8546        8901
   196            8580        8955
   197            8580        9009
   198            8648        9064
   199            8668        9118
   200            8732        9173
   201            8766        9227
   202            8766        9282
   203            8796        9336
   204            8868        9391
   205            8880        9446
   206            8968        9501
   207            8996        9555
   208            9056        9610
   209            9104        9665
   210            9118        9720
   211            9170        9775
   212            9258        9830
   213            9256        9885
   214            9248        9940
   215            9366        9995
   216            9396       10050
   217            9438       10106
   218            9520       10161
   219            9532       10216
   220            9556       10271
   221            9572       10327
   222            9664       10382
   223            9616       10438
   224            9702       10493
   225            9890       10549
   226            9966       10604
   227           10028       10660
   228           10030       10715
   229           10046       10771
   230           10116       10827
   231           10112       10883
   232           10208       10938
   233           10140       10994
   234           10272       11050
   235           10310       11106
   236           10380       11162
   237           10400       11218
   238           10462       11274
   239           10508       11330
   240           10488       11386
   241           10668       11442
   242           10658       11498
   243           10702       11554
   244           10728       11611
   245           10866       11667
   246           10866       11723
   247           10884       11779
   248           10864       11836
   249           10954       11892
   250           11038       11949
   251           11102       12005
   252           11176       12062
   253           11132       12118
   254           11260       12175
   255           11260       12231
   256           11310       12288
   257           12560       12345
   258           12814       12401
   259           12686       12458
   260           12640       12515
   261           12968       12572
   262           12986       12629
   263           12954       12685
   264           13046       12742
   265           13002       12799
   266           13080       12856
   267           13058       12913
   268           13194       12970
   269           13124       13027
   270           13160       13084
   271           13100       13142
   272           13254       13199
   273           13362       13256
   274           13428       13313
   275           13428       13370
   276           13422       13428
   277           13428       13485
   278           13496       13542
   279           13628       13600
   280           13510       13657
   281           13658       13715
   282           13688       13772
   283           13582       13830
   284           13746       13887
   285           13802       13945
   286           13808       14002
   287           13834       14060
   288           13886       14118
   289           13990       14175
   290           14116       14233
   291           14136       14291
   292           14210       14349
   293           14274       14406
   294           14194       14464
   295           14224       14522
   296           14336       14580
   297           14356       14638
   298           14348       14696
   299           14374       14754
   300           14438       14812
   301           14434       14870
   302           14526       14928
   303           14592       14986
   304           14630       15044
   305           14722       15102
   306           14786       15161
   307           14772       15219
   308           14794       15277
   309           14860       15335
   310           14832       15394
   311           14870       15452
   312           14878       15510
   313           14938       15569
   314           15098       15627
   315           15060       15686
   316           15112       15744
   317           15168       15802
   318           15238       15861
   319           15184       15920
   320           15280       15978
   321           15594       16037
   322           15678       16095
   323           15678       16154
   324           15752       16213
   325           15782       16271
   326           15774       16330
   327           15800       16389
   328           15900       16448
   329           15996       16506
   330           15978       16565
   331           16034       16624
   332           16088       16683
   333           16132       16742
   334           16156       16801
   335           16152       16860
   336           16188       16919
   337           16346       16978
   338           16348       17037
   339           16374       17096
   340           16318       17155
   341           16396       17214
   342           16486       17273
   343           16488       17333
   344           16544       17392
   345           16678       17451
   346           16680       17510
   347           16758       17570
   348           16704       17629
   349           16760       17688
   350           16836       17748
   351           16834       17807
   352           16864       17866
   353           17076       17926
   354           17102       17985
   355           17122       18045
   356           17174       18104
   357           17178       18164
   358           17296       18223
   359           17296       18283
   360           17362       18342
   361           17446       18402
   362           17380       18462
   363           17422       18521
   364           17558       18581
   365           17566       18641
   366           17572       18700
   367           17608       18760
   368           17738       18820
   369           17840       18880
   370           17888       18940
   371           17880       19000
   372           17992       19059
   373           18010       19119
   374           18006       19179
   375           18052       19239
   376           18128       19299
   377           18244       19359
   378           18140       19419
   379           18232       19479
   380           18306       19539
   381           18334       19599
   382           18476       19659
   383           18460       19720
   384           18588       19780
   385           19288       19840
   386           19052       19900
   387           19288       19960
   388           19360       20021
   389           19268       20081
   390           19348       20141
   391           19368       20201
   392           19510       20262
   393           19578       20322
   394           19600       20383
   395           19544       20443
   396           19614       20503
   397           19732       20564
   398           19734       20624
   399           19758       20685
   400           19686       20745
   401           19834       20806
   402           19830       20866
   403           19970       20927
   404           20016       20988
   405           19976       21048
   406           20000       21109
   407           20088       21169
   408           20126       21230
   409           20086       21291
   410           20198       21352
   411           20326       21412
   412           20298       21473
   413           20398       21534
   414           20390       21595
   415           20510       21655
   416           20486       21716
   417           20692       21777
   418           20684       21838
   419           20724       21899
   420           20872       21960
   421           20844       22021
   422           20938       22082
   423           20874       22143
   424           20938       22204
   425           21080       22265
   426           21086       22326
   427           21152       22387
   428           21190       22448
   429           21164       22509
   430           21272       22570
   431           21258       22631
   432           21276       22693
   433           21484       22754
   434           21476       22815
   435           21592       22876
   436           21568       22938
   437           21596       22999
   438           21534       23060
   439           21692       23121
   440           21732       23183
   441           21766       23244
   442           21854       23306
   443           21864       23367
   444           21900       23428
   445           22006       23490
   446           22014       23551
   447           22042       23613
   448           22134       23674
   449           22474       23736
   450           22382       23797
   451           22458       23859
   452           22610       23920
   453           22578       23982
   454           22666       24044
   455           22542       24105
   456           22690       24167
   457           22838       24228
   458           22876       24290
   459           22898       24352
   460           22942       24414
   461           22950       24475
   462           22958       24537
   463           23034       24599
   464           22986       24661
   465           23264       24722
   466           23278       24784
   467           23328       24846
   468           23338       24908
   469           23316       24970
   470           23486       25032
   471           23500       25094
   472           23496       25156
   473           23570       25218
   474           23682       25280
   475           23672       25342
   476           23688       25404
   477           23876       25466
   478           23826       25528
   479           23852       25590
   480           24000       25652
   481           24198       25714
   482           24114       25776
   483           24144       25838
   484           24198       25900
   485           24202       25963
   486           24248       26025
   487           24312       26087
   488           24420       26149
   489           24522       26211
   490           24564       26274
   491           24554       26336
   492           24614       26398
   493           24652       26461
   494           24764       26523
   495           24814       26585
   496           24744       26648
   497           24810       26710
   498           25000       26772
   499           25044       26835
   500           25024       26897
   501           25152       26960
   502           25178       27022
   503           25240       27085
   504           25226       27147
   505           25282       27210
   506           25350       27272
   507           25442       27335
   508           25536       27398
   509           25526       27460
   510           25672       27523
   511           25576       27585
   512           25710       27648


Question: Show that the number of compares used by mergesort is monotonically increasing (C(N+1) > C(N) for all N > 0).

Answer:
For top-down mergesort in the worst case, the number of compares C(N) satisfies

C(1) = 0
C(N) = C(floor(N/2)) + C(ceil(N/2)) + N - 1

The merge of two sorted subarrays whose total length is N uses at most N - 1 compares. To prove C(N + 1) > C(N), compare the recurrences. Increasing the input size by one increases one of the two recursive subproblem sizes by one and increases the final merge term from N - 1 to N. By induction, the recursive part cannot decrease, and the merge term increases by exactly one. Therefore C(N + 1) > C(N) for all N > 0.

This statement is about the worst-case compare count. A randomized experiment on particular inputs can show non-monotone realized compare counts because a merge may finish early when one side is exhausted.


Question: Suppose that Algorithm 2.4 is modified to skip the call on merge() whenever a[mid] <= a[mid+1]. Prove that the number of compares used to mergesort a sorted array is linear.

Answer:
2.2.8

Since the array is already sorted, merge() will always be skipped. So there won't be any values copied from the aux array to the original array (only values copied from the original array to the aux array).
Therefore, there will be only 1 compare for every subarray, which is a linear operation.

When N is a power of 2, the number of compares will satisfy the recurrence
T(N) = 2 T(N/2) + 1, with T(1) = 0


Question: Use of a static array like aux[] is inadvisable in library software because multiple clients might use the class concurrently. Give an implementation of Merge that does not use a static array. Do not make aux[] local to merge() (see the Q&A for this section). Hint: Pass the auxiliary array as an argument to the recursive sort().

Answer:
package chapter2.section2;

import edu.princeton.cs.algs4.StdRandom;

/**
 * Created by Rene Argento on 11/02/17.
 */
public class Exercise9 {

    public static void main(String[] args) {

        Comparable[] array = generateRandomArray(1000);
        topDownMergeSort(array);
    }

    private static Comparable[] generateRandomArray(int arrayLength) {
        Comparable[] array = new Comparable[arrayLength];

        for (int i = 0; i < arrayLength; i++) {
            array[i] = StdRandom.uniform();
        }

        return array;
    }

    private static void topDownMergeSort(Comparable[] array) {
        Comparable[] aux = new Comparable[array.length];

        topDownMergeSort(array, aux, 0, array.length - 1);
    }

    private static void topDownMergeSort(Comparable[] array, Comparable[] aux, int low, int high) {

        if (high <= low) {
            return;
        }

        int middle = low + (high - low) / 2;

        topDownMergeSort(array, aux, low, middle);
        topDownMergeSort(array, aux, middle + 1, high);

        merge(array, aux, low, middle, high);
    }

    @SuppressWarnings("unchecked")
    private static void merge(Comparable[] array, Comparable[] aux, int low, int middle, int high) {
        for (int i = low; i <= high; i++) {
            aux[i] = array[i];
        }

        int indexLeft = low;
        int indexRight = middle + 1;
        int arrayIndex = low;

        while (indexLeft <= middle && indexRight <= high) {
            if (aux[indexLeft].compareTo(aux[indexRight]) <= 0) {
                array[arrayIndex] = aux[indexLeft];
                indexLeft++;
            } else {
                array[arrayIndex] = aux[indexRight];
                indexRight++;
            }

            arrayIndex++;
        }

        while (indexLeft <= middle) {
            array[arrayIndex] = aux[indexLeft];

            indexLeft++;
            arrayIndex++;
        }
    }
}


Question: Faster merge. Implement a version of merge() that copies the second half of a[] to aux[] in decreasing order and then does the merge back to a[]. This change allows you to remove the code to test that each of the halves has been exhausted from the inner loop. Note: The resulting sort is not stable (see page 341).

Answer:
package chapter2.section2;

import util.ArrayGenerator;

/**
 * Created by Rene Argento on 12/02/17.
 */
@SuppressWarnings("rawtypes")
public class Exercise10_FasterMerge {

    public static void main(String[] args) {
        Comparable[] array = ArrayGenerator.generateRandomArray(1000);
        topDownMergeSort(array);
    }

    public static void topDownMergeSort(Comparable[] array) {
        Comparable[] aux = new Comparable[array.length];
        topDownMergeSort(array, aux, 0, array.length - 1);
    }

    private static void topDownMergeSort(Comparable[] array, Comparable[] aux, int low, int high) {
        if (high <= low) {
            return;
        }
        int middle = low + (high - low) / 2;

        topDownMergeSort(array, aux, low, middle);
        topDownMergeSort(array, aux, middle + 1, high);
        merge(array, aux, low, middle, high);
    }

    @SuppressWarnings("unchecked")
    private static void merge(Comparable[] array, Comparable[] aux, int low, int middle, int high) {
        int auxIndex = low;

        for (int i = low; i <= middle; i++) {
            aux[auxIndex] = array[i];
            auxIndex++;
        }

        for (int i = high; i >= middle + 1; i--) {
            aux[auxIndex] = array[i];
            auxIndex++;
        }

        int indexLeft = low;
        int indexRight = high;
        int arrayIndex = low;

        while (indexLeft <= middle) {
            if (aux[indexLeft].compareTo(aux[indexRight]) <= 0) {
                array[arrayIndex] = aux[indexLeft];
                indexLeft++;
            } else {
                array[arrayIndex] = aux[indexRight];
                indexRight--;
            }
            arrayIndex++;
        }
    }
}


Question: Lower bound for average case. Prove that the expected number of compares used by any compare-based sorting algorithm must be at least ~N lg N (assuming that all possible orderings of the input are equally likely). Hint: The expected number of compares is at least the external path length of the compare tree (the sum of the lengths of the paths from the root to all leaves), which is minimized when it is balanced.

Answer:
2.2.13 - Lower bound for average case

Based on: https://www.cs.cmu.edu/~avrim/451f11/lectures/lect0913.pdf

Theorem: For any deterministic comparison-based sorting algorithm A, the average-case number of comparisons (the number of comparisons on average on a randomly chosen permutation of n distinct elements) is at least log2(n!) rounded up.

Based on the Stirlings approximation, log2(n!) -> ~ N log2(N)

Proof: Let S be the set of all n! possible orderings of n distinct elements.
These each require a different permutation to be produced as output.
Let's now build out the entire decision tree for algorithm A on S: the tree we get by looking at all the different question/answer paths we get by running algorithm A on the inputs in S.
This tree has n! leaves, where the depth of a leaf is the number of comparisons performed by the sorting algorithm on that input.
Our goal is to show that the average depth of the leaves must be at least log2(n!) rounded up (for the worst-case, we only care about the maximum depth).

If the tree is completely balanced, then each leaf is at depth log2(n!) (rounded up or rounded down) and we are done.
To prove the theorem, we just need to show that out of all binary trees on a given number of leaves, the one that minimizes their average depth is a completely balanced tree.
This is not too hard to see: given some unbalanced tree, we take two sibling leaves at largest depth and move them to be children of the leaf of smallest depth.
Since the difference between the largest depth and the smallest depth is at least 2 (otherwise the tree would be balanced), this operation reduces the average depth of the leaves.
Specifically, if the smaller depth is "d" and the larger depth is "D", we have removed two leaves of depth "D" and one of depth "d", and we have added two leaves of depth "d + 1" and one of depth "D - 1".
Since any unbalanced tree can be modified to have a smaller average depth, such a tree cannot be one that minimizes average depth, and therefore the tree of smallest average depth must in fact be balanced.


Question: Merging sorted queues. Develop a static method that takes two queues of sorted items as arguments and returns a queue that results from merging the queues into sorted order.

Answer:
package chapter2.section2;

import edu.princeton.cs.algs4.Queue;
import edu.princeton.cs.algs4.StdOut;

/**
 * Created by Rene Argento on 13/02/17.
 */
// Thanks to dragon-dreamer (https://github.com/dragon-dreamer) for suggesting a simpler method to merge the queues:
// https://github.com/reneargento/algorithms-sedgewick-wayne/issues/107
@SuppressWarnings("unchecked")
public class Exercise14_MergingSortedQueues {

    public static void main(String[] args) {

        Queue<Comparable> queue1 = new Queue<>();
        queue1.enqueue(1);
        queue1.enqueue(3);
        queue1.enqueue(5);
        queue1.enqueue(7);
        queue1.enqueue(9);

        Queue<Comparable> queue2 = new Queue<>();
        queue2.enqueue(2);
        queue2.enqueue(4);
        queue2.enqueue(6);
        queue2.enqueue(8);

        Queue<Comparable> mergedQueue = mergeQueues(queue1, queue2);

        StdOut.print("Merged queues: ");
        for (Comparable item : mergedQueue) {
            StdOut.print(item + " ");
        }
        StdOut.println("\nExpected: 1 2 3 4 5 6 7 8 9");
    }

    public static Queue<Comparable> mergeQueues(Queue<Comparable> queue1, Queue<Comparable> queue2) {
        Queue<Comparable> mergedQueue = new Queue<>();

        while (!queue1.isEmpty() && !queue2.isEmpty()) {
            if (queue1.peek().compareTo(queue2.peek()) <= 0) {
                mergedQueue.enqueue(queue1.dequeue());
            } else {
                mergedQueue.enqueue(queue2.dequeue());
            }
        }

        while (!queue1.isEmpty()) {
            mergedQueue.enqueue(queue1.dequeue());
        }
        while (!queue2.isEmpty()) {
            mergedQueue.enqueue(queue2.dequeue());
        }
        return mergedQueue;
    }
}


Question: Bottom-up queue mergesort. Develop a bottom-up mergesort implementation based on the following approach: Given N items, create N queues, each containing one of the items. Create a queue of the N queues. Then repeatedly apply the merging operation of Exercise 2.2.14 to the first two queues and reinsert the merged queue at the end. Repeat until the queue of queues contains only one queue.

Answer:
package chapter2.section2;

import edu.princeton.cs.algs4.Queue;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;

/**
 * Created by Rene Argento on 13/02/17.
 */
public class Exercise15_BottomUpQueueMergesort {

    public static void main(String[] args) {

        Comparable[] array = generateRandomArray(10);

        Queue<Queue<Comparable>> mergedQueue = bottomUpQueueMergesort(array);

        StdOut.println("Merged queues:");
        for (Comparable item : mergedQueue.peek()) {
            StdOut.print(item + " ");
        }
    }

    private static Comparable[] generateRandomArray(int arrayLength) {
        Comparable[] array = new Comparable[arrayLength];

        for (int i = 0; i < arrayLength; i++) {
            array[i] = StdRandom.uniform();
        }

        return array;
    }

    private static Queue<Queue<Comparable>> bottomUpQueueMergesort(Comparable[] array) {
        Queue<Queue<Comparable>> sortedQueues = new Queue<>();

        for (Comparable value : array) {
            Queue<Comparable> queue = new Queue<>();
            queue.enqueue(value);

            sortedQueues.enqueue(queue);
        }

        while (sortedQueues.size() > 1) {
            Queue<Comparable> queue1 = sortedQueues.dequeue();
            Queue<Comparable> queue2 = sortedQueues.dequeue();

            Queue<Comparable> mergedQueue = Exercise14_MergingSortedQueues.mergeQueues(queue1, queue2);
            sortedQueues.enqueue(mergedQueue);
        }
        return sortedQueues;
    }
}


Question: Indirect sort. Develop and implement a version of mergesort that does not rearrange the array, but returns an int[] array perm such that perm[i] is the index of the ith smallest entry in the array.

Answer:
package chapter2.section2;

import edu.princeton.cs.algs4.StdOut;

/**
 * Created by Rene Argento on 18/02/17.
 */
//Based on http://algs4.cs.princeton.edu/22mergesort/Merge.java.html
public class Exercise20_IndexSort {

    public static void main(String[] args) {

        Comparable[] array1 = generateArray1();
        int[] indexSortedArray1 = indexSort(array1);

        int[] expectedIndexSortedArray1 = {5, 4, 6, 3, 7, 2, 8, 1, 9, 0};
        if (validate(expectedIndexSortedArray1, indexSortedArray1)) {
            StdOut.println("Index sorted OK");
        } else {
            StdOut.println("Index sorted NOT OK");
        }
        StdOut.println("Expected: Index sorted OK\n");

        Comparable[] array2 = generateArray2();
        int[] indexSortedArray2 = indexSort(array2);

        int[] expectedIndexSortedArray2 = {3, 2, 1, 0};
        if (validate(expectedIndexSortedArray2, indexSortedArray2)) {
            StdOut.println("Index sorted OK");
        } else {
            StdOut.println("Index sorted NOT OK");
        }
        StdOut.println("Expected: Index sorted OK");
    }

    private static Comparable[] generateArray1() {
        Comparable[] array = new Comparable[10];

        array[0] = 10; //Correct index: 9
        array[1] = 9; //Correct index: 7
        array[2] = 8; //Correct index: 5
        array[3] = 7; //Correct index: 3
        array[4] = 6; //Correct index: 1
        array[5] = 5; //Correct index: 0
        array[6] = 6; //Correct index: 2
        array[7] = 7; //Correct index: 4
        array[8] = 8; //Correct index: 6
        array[9] = 9; //Correct index: 8

        //Expected: [5, 4, 6, 3, 7, 2, 8, 1, 9, 0]

        return array;
    }

    private static Comparable[] generateArray2() {

        Comparable[] array = new Comparable[4];

        array[0] = 4; //Correct index: 3
        array[1] = 3; //Correct index: 2
        array[2] = 2; //Correct index: 1
        array[3] = 1; //Correct index: 0

        //Expected: [3, 2, 1, 0]

        return array;
    }

    private static int[] indexSort(Comparable[] array) {
        int[] aux = new int[array.length];
        int[] indexSort = new int[array.length];

        for (int i = 0; i < array.length; i++) {
            indexSort[i] = i;
        }

        indexSort(array, aux, indexSort, 0, array.length - 1);
        return indexSort;
    }

    private static void indexSort(Comparable[] array, int[] aux, int[] indexSort, int low, int high) {
        if (low >= high) {
            return;
        }

        int middle = low + (high - low) / 2;

        indexSort(array, aux, indexSort, low, middle);
        indexSort(array, aux, indexSort, middle + 1, high);

        merge(array, aux, indexSort, low, middle, high);
    }

    @SuppressWarnings("unchecked")
    private static void merge(Comparable[] array, int[] aux, int[] indexSort, int low, int middle, int high) {
        for (int i = low; i <= high; i++) {
            aux[i] = indexSort[i];
        }

        int leftIndex = low;
        int rightIndex = middle + 1;
        int arrayIndex = low;

        while (leftIndex <= middle && rightIndex <= high) {
            if (array[aux[leftIndex]].compareTo(array[aux[rightIndex]]) <= 0) {
                indexSort[arrayIndex] = aux[leftIndex];

                leftIndex++;
            } else {
                indexSort[arrayIndex] = aux[rightIndex];
                rightIndex++;
            }

            arrayIndex++;
        }

        while (leftIndex <= middle) {
            indexSort[arrayIndex] = aux[leftIndex];
            leftIndex++;
            arrayIndex++;
        }
    }

    private static boolean validate(int[] expectedIndexSortedArray, int[] indexSortedArray) {
        if (expectedIndexSortedArray.length != indexSortedArray.length) {
            return false;
        }

        for (int i = 0; i < expectedIndexSortedArray.length; i++) {
            if (expectedIndexSortedArray[i] != indexSortedArray[i]) {
                return false;
            }
        }
        return true;
    }
}


Question: Show, in the style of the trace given with partition(), how that method partitions the array E A S Y Q U E S T I O N.

Answer:
2.3.1
                                             a[]
                         i   j   0  1  2  3  4  5  6  7  8  9  10  11
initial values           0  12   E  A  S  Y  Q  U  E  S  T  I   O   N
scan left, scan right    2   6   E  A  S  Y  Q  U  E  S  T  I   O   N
exchange                 2   6   E  A  E  Y  Q  U  S  S  T  I   O   N
scan left, scan right    3   2   E  A  E  Y  Q  U  S  S  T  I   O   N
final exchange               2   E  A  E  Y  Q  U  S  S  T  I   O   N
result                       2   E  A  E  Y  Q  U  S  S  T  I   O   N

Thanks to Forest-Lee (https://github.com/Forest-Lee) for mentioning that we should have the last line with the result.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/292


Question: Show, in the style of the quicksort trace given in this section, how quicksort sorts the array E A S Y Q U E S T I O N (for the purposes of this exercise, ignore the initial shuffle).

Answer:
2.3.2
                             a[]
lo  j  hi   0  1  2  3  4  5  6  7  8  9  10  11
            E  A  S  Y  Q  U  E  S  T  I   O   N
 0  2  11   E  A  E  Y  Q  U  S  S  T  I   O   N
 0  1   1   A  E  E  Y  Q  U  S  S  T  I   O   N
 0      0   A  E  E  Y  Q  U  S  S  T  I   O   N
 3 11  11   A  E  E  N  Q  U  S  S  T  I   O   Y
 3  4  10   A  E  E  I  N  U  S  S  T  Q   O   Y
 3      3   A  E  E  I  N  U  S  S  T  Q   O   Y
 5 10  10   A  E  E  I  N  O  S  S  T  Q   U   Y
 5  5   9   A  E  E  I  N  O  S  S  T  Q   U   Y
 6  7   9   A  E  E  I  N  O  Q  S  T  S   U   Y
 6      6   A  E  E  I  N  O  Q  S  T  S   U   Y
 8  9   9   A  E  E  I  N  O  Q  S  S  T   U   Y
            A  E  E  I  N  O  Q  S  S  T   U   Y

Thanks to Shahin Ansari for finding that one extra line in the trace could be removed.


Question: What is the maximum number of times during the execution of Quick.sort() that the largest item can be exchanged, for an array of length N?

Answer:
2.3.3

The maximum number of times during the execution of Quick.sort() that the largest item can be exchanged, for an
array of length N is floor(N / 2).
Note that this answer is specific to this version of quicksort in which the first element is always selected as the pivot.

Reference: https://stackoverflow.com/questions/43263249/number-of-largest-element-exchanges-for-quicksort

Thanks to ajfg93 (https://github.com/ajfg93) for correcting this exercise.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/30


Question: Suppose that the initial random shuffle is omitted. Give six arrays of ten elements for which Quick.sort() uses the worst-case number of compares.

Answer:
2.3.4

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
[11, 10, 9, 8, 7, 6, 5, 4, 3, 2]
[12, 11, 10, 9, 8, 7, 6, 5, 4, 3]


Question: Give a code fragment that sorts an array that is known to consist of items having just two distinct keys.

Answer:
package chapter2.section3;

import edu.princeton.cs.algs4.StdOut;
import util.ArrayGenerator;

import java.util.StringJoiner;

/**
 * Created by Rene Argento on 04/03/17.
 */
public class Exercise5 {

    public static void main(String[] args) {
        int arrayLength = Integer.parseInt(args[0]);
        Comparable array[] = ArrayGenerator.generateRandomArrayWith2Values(arrayLength);

        StringJoiner originalArray = new StringJoiner(" ");
        for (Comparable element : array) {
            originalArray.add(String.valueOf(element));
        }
        StdOut.println("Original array: " + originalArray);

        sort3WayPartitioning(array);

        StringJoiner sortedArray = new StringJoiner(" ");
        for (Comparable element : array) {
            sortedArray.add(String.valueOf(element));
        }
        StdOut.println("Sorted array: " + sortedArray);
    }

    @SuppressWarnings("unchecked")
    private static void sort3WayPartitioning(Comparable[] array) {

        int lt = 0;
        int gt = array.length - 1;
        int i = lt + 1;

        Comparable pivot = array[0];

        while (i <= gt) {
            int comparison = array[i].compareTo(pivot);

            if (comparison < 0) {
                exchange(array, lt, i);
                lt++;
                i++;
            } else if (comparison > 0) {
                exchange(array, i, gt);
                gt--;
            } else {
                i++;
            }
        }
    }

    private static void exchange(Comparable[] array, int position1, int position2) {
        Comparable temp = array[position1];
        array[position1] = array[position2];
        array[position2] = temp;
    }
}


Question: Write a program to compute the exact value of CN, and compare the exact value with the approximation 2N ln N, for N = 100, 1,000, and 10,000.

Answer:
For standard quicksort with random distinct keys,

`C_0 = C_1 = 0`

and, for `N >= 2`,

`C_N = N + 1 + (2 / N) * (C_0 + C_1 + ... + C_{N-1})`.

Equivalently, `C_N = 2(N + 1)H_N - 4N`.

| N | exact C_N | 2N ln N |
|---:|---:|---:|
| 100 | 648 | 921 |
| 1,000 | 10,986 | 13,816 |
| 10,000 | 155,772 | 184,207 |

The previous answer used empirical-looking counts. The exact values above are the expected number of compares from the recurrence.


Question: Find the expected number of subarrays of size 0, 1, and 2 when quicksort is used to sort an array of N items with distinct keys. If you are mathematically inclined, do the math; if not, run some experiments to develop hypotheses.

Answer:
2.3.7

Array Size |  SubArrays Size 0 |  SubArrays Size 1 |   SubArrays Size 2
      1000                 325                 338                  174
      2000                 657                 672                  333
      4000                1383                1309                  681
      8000                2639                2681                 1329
     16000                5327                5337                 2662

Hypothesis:
The expected number of subarrays of size 0, 1 and 2 when quicksort is used to sort an array of N items with distinct keys is:
Subarray size 0: 1/3 N
Subarray size 1: 1/3 N
Subarray size 2: 1/6 N


Question: About how many compares will Quick.sort() make when sorting an array of N items that are all equal?

Answer:
2.3.8

When sorting an array of N items that are all equal, Quick.sort() will make approximately N lg N compares.
Each partition will divide the array in half, plus or minus one.


Question: Explain what happens when Quick.sort() is run on an array having items with just two distinct keys, and then explain what happens when it is run on an array having just three distinct keys.

Answer:
2.3.9

On both cases (when Quick.sort() is run on arrays having items with just two or three distinct keys) there is a high occurrence of subarrays consisting solely of items with equal keys. To improve performance when sorting such arrays (from linearithmic to linear) quicksort with 3-way partitioning should be used.


Question: Chebyshev’s inequality says that the probability that a random variable is more than k standard deviations away from the mean is less than 1/k^2. For N = 1 million, use Chebyshev’s inequality to bound the probability that the number of compares used by quicksort is more than 100 billion (.1 N^2).

Answer:
2.3.10

There are 1 million elements, so N = 1,000,000.
As mentioned on the book, quicksort uses ~2N ln N compares on the average case to sort N keys.
Therefore, on average there will be 27,620,000 compares.

As also mentioned on the book, the standard deviation of the number of compares is about .65 N, which in this case is 650,000.
With this information, the probability can be computed as follows:

Difference between target compares and average compares = 100,000,000,000 - 27,620,000 = 99,972,380,000
k = number of standard deviations = 99,972,380,000 / 650,000 ~= 153,804
Probability < 1 / k^2
Probability < 1 / (153,804)^2
Probability < 1 / 23,655,670,416
Probability < 0.000000000042273 = 0.0000000042273%

Therefore, the probability that the number of compares used by quicksort for N = 1,000,000 is more than 100 billion is less than 0.0000000042273%.


Question: What is the recursive depth of quicksort, in the best, worst, and average cases? This is the size of the stack that the system needs to keep track of the recursive calls. See Exercise 2.3.20 for a way to guarantee that the recursive depth is logarithmic in the worst case.

Answer:
2.3.13

Recursive depth in the best case: logarithmic
Recursive depth in the worst case: linear
Recursive depth in the average case: logarithmic (if the pivot is chosen at random or if the array is shuffled before the sort begins).


Question: Prove that when running quicksort on an array with N distinct items, the probability of comparing the ith and jth largest items is 2/(j - i + 1). Then use this result to prove Proposition K.

Answer:
2.3.14

The ith and jth elements will be compared if either of them is selected as pivot.
In an array of size (j - i + 1), the probability of choosing either the ith or the jth element as the pivot is 2 / (j - i + 1).

Therefore, when running quicksort on an array with N distinct items, the probability of comparing the ith and the jth smallest items is 2 / (j - i + 1).

Based on: http://stackoverflow.com/questions/2750726/randomized-quicksort-probability-of-two-elements-comparison

Proposition K says that quicksort uses ~ 2N ln N compares (and one-sixth that many exchanges) on the average to sort an array of length N with distinct keys.

Consider the pivot element as k.

1- When k > both ith and jth elements: in this case A[i] and A[j] are not compared to each other in this recursive call, but both are passed on to the first recursive call (so they might be compared in the future).
2- When k < both ith and jth elements: similarly, in this case A[i] and A[j] are not compared to each other but both are passed on to the second recursive call.

As we have seen, the probability Pr of comparing the ith and jth elements is:
Pr[Cij = 1] = 2 / (j - i + 1)

Combining both 1 and 2 statements yields:

C = 2 * SUM(from i=1 to N) * SUM(from j = i + 1 to N) * 1 / (j - i + 1)

Note that for each fixed i, the inner sum is:

1/2 + 1/3 + 1/4 + ... + 1 / (n - i + 1) <= SUM(from k = 2 to N) * 1/k

We can upper bound the right-hand side by the area under the curve f(x) = 1/x. In other words:
SUM(from k = 2 to N) * 1/k <= LIM(from 1 to N) * dx / x = ln * x |(from 1 to N) = ln N

Putting it all together, we have

C = 2 * SUM(from i=1 to N) * SUM(from j = i + 1 to N) * 1 / (j - i + 1) <= 2N * SUM(from k = 2 to N) * 1/k <= 2N ln N,

which completes the proof.


Question: Nuts and bolts. (G. J. E. Rawlins) You have a mixed pile of N nuts and N bolts and need to quickly find the corresponding pairs of nuts and bolts. Each nut matches exactly one bolt, and each bolt matches exactly one nut. By fitting a nut and bolt together, you can see which is bigger, but it is not possible to directly compare two nuts or two bolts. Give an efficient method for solving the problem.

Answer:
2.3.15 - Nuts and bolts

Since each nut matches exactly one bolt, the array of nuts and the array of bolts have distinct elements.
To avoid a O(N^2) complexity, initially I would shuffle the nuts array.

I would then use Quicksort's partition method:
1- Select a nut as the pivot (since the array is shuffled it is safe to always select the first nut).
2- Using that pivot, partition the bolts array. This would result in the bolts array with a bolt (matching the nut pivot) in the correct place, all bolts smaller than it on its left and all bolts bigger than it on its right.
3- Use the bolt found on the previous step as a pivot and partition the nuts array.
4- Split the bolt array into two sub-arrays: one array with bolts smaller than the bolt found on step 2, and another array with bolts bigger than it.
5- Do the same split for the nuts array, based on the nut found on step 3.

I would repeat these steps recursively on the corresponding nut and bolt sub-arrays.
At the end, I would iterate over the sorted arrays and connect all nuts and bolts based on their index.

This method would do 2 * N operations for finding the partitions (N operations for the nuts array and N operations for the bolts array), lg N times, and would yield a complexity of O(N lg N).

Based on: https://www.geeksforgeeks.org/nuts-bolts-problem-lock-key-problem/
Thanks to dragon-dreamer (https://github.com/dragon-dreamer) for suggesting a simpler method for this exercise.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/109


Question: Nonrecursive quicksort. Implement a nonrecursive version of quicksort based on a main loop where a subarray is popped from a stack to be partitioned, and the resulting subarrays are pushed onto the stack. Note: Push the larger of the subarrays onto the stack first, which guarantees that the stack will have at most lg N entries.

Answer:
// Exercise20_NonrecursiveQuicksort.java
package chapter2.section3;

import edu.princeton.cs.algs4.Stack;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.Stopwatch;
import util.ArrayUtil;
import util.ArrayGenerator;

import java.util.Map;

/**
 * Created by Rene Argento on 07/03/17.
 */
// Thanks to dragon-dreamer (https://github.com/dragon-dreamer) for noticing that some redundant checks could be removed.
// https://github.com/reneargento/algorithms-sedgewick-wayne/issues/110
public class Exercise20_NonrecursiveQuicksort {

    private static class QuickSortRange {
        int low;
        int high;

        QuickSortRange(int low, int high) {
            this.low = low;
            this.high = high;
        }
    }

    // Parameters example: 8 131072
    public static void main(String[] args) {
        int numberOfExperiments = Integer.parseInt(args[0]);
        int initialArraySize = Integer.parseInt(args[1]);

        Map<Integer, Comparable[]> allInputArrays = ArrayGenerator.generateAllArrays(numberOfExperiments, initialArraySize, 2);

        doExperiment(numberOfExperiments, initialArraySize, allInputArrays);
    }

    private static void doExperiment(int numberOfExperiments, int initialArraySize, Map<Integer, Comparable[]> allInputArrays) {
        StdOut.printf("%13s %23s %22s\n", "Array Size | ", "QuickSort Running Time |", "Nonrecursive QuickSort");

        int arraySize = initialArraySize;

        for (int i = 0; i < numberOfExperiments; i++) {

            Comparable[] originalArray = allInputArrays.get(i);
            Comparable[] arrayCopy1 = new Comparable[originalArray.length];
            System.arraycopy(originalArray, 0, arrayCopy1, 0, originalArray.length);

            // Default QuickSort
            Stopwatch defaultQuickSortTimer = new Stopwatch();

            QuickSort.quickSort(originalArray);

            double defaultQuickSortRunningTime = defaultQuickSortTimer.elapsedTime();

            // Nonrecursive QuickSort
            Stopwatch nonRecursiveQuickSortTimer = new Stopwatch();

            nonRecursiveQuickSort(arrayCopy1);

            double nonRecursiveQuickSortRunningTime = nonRecursiveQuickSortTimer.elapsedTime();

            printResults(arraySize, defaultQuickSortRunningTime, nonRecursiveQuickSortRunningTime);

            arraySize *= 2;
        }
    }

    private static void nonRecursiveQuickSort(Comparable[] array) {
        StdRandom.shuffle(array);
        quickSort(array, 0, array.length - 1);
    }

    private static void quickSort(Comparable[] array, int low, int high) {
        Stack<QuickSortRange> stack = new Stack<>();

        QuickSortRange quickSortRange = new QuickSortRange(low, high);
        stack.push(quickSortRange);

        while (stack.size() > 0) {
            QuickSortRange currentQuickSortRange = stack.pop();

            int partition = partition(array, currentQuickSortRange.low, currentQuickSortRange.high);
            QuickSortRange leftQuickSortRange = new QuickSortRange(currentQuickSortRange.low, partition - 1);
            QuickSortRange rightQuickSortRange = new QuickSortRange(partition + 1, currentQuickSortRange.high);

            // Size = right - left + 1
            int leftSubArraySize = partition - currentQuickSortRange.low;
            int rightSubArraySize = currentQuickSortRange.high - partition;

            // Push the larger sub array first to guarantee that the stack will have at most lg N entries
            if (leftSubArraySize > rightSubArraySize) {
                if (leftSubArraySize > 1) {
                    stack.push(leftQuickSortRange);
                }
                if (rightSubArraySize > 1) {
                    stack.push(rightQuickSortRange);
                }
            } else {
                if (rightSubArraySize > 1) {
                    stack.push(rightQuickSortRange);
                }
                if (leftSubArraySize > 1) {
                    stack.push(leftQuickSortRange);
                }
            }
        }
    }

    private static int partition(Comparable[] array, int low, int high) {
        Comparable pivot = array[low];

        int i = low;
        int j = high + 1;

        while (true) {
            while (ArrayUtil.less(array[++i], pivot)) {
                if (i == high) {
                    break;
                }
            }

            while (ArrayUtil.less(pivot, array[--j])) {
                if (j == low) {
                    break;
                }
            }

            if (i >= j) {
                break;
            }

            ArrayUtil.exchange(array, i, j);
        }

        // Place pivot in the right place
        ArrayUtil.exchange(array, low, j);
        return j;
    }

    private static void printResults(int arraySize, double defaultQuickSortRunningTime, double nonRecursiveQuickSort) {
        StdOut.printf("%10d %25.1f %24.1f\n", arraySize, defaultQuickSortRunningTime, nonRecursiveQuickSort);
    }
}

Additional notes/results:
2.3.20 - Nonrecursive QuickSort

The recursive implementation has a better running time than the non recursive implementation.

Array Size |  QuickSort Running Time | Nonrecursive QuickSort
    131072                       0.1                      0.1
    262144                       0.1                      0.8
    524288                       0.2                      0.2
   1048576                       0.4                      0.4
   2097152                       0.9                      1.7
   4194304                       2.3                      3.0
   8388608                       5.5                      6.1
  16777216                      11.6                     12.3


Question: Java system sort. Add to your implementation from Exercise 2.3.22 code to use the Tukey ninther to compute the partitioning item—choose three sets of three items, take the median of each, then use the median of the three medians as the partitioning item. Also, add a cutoff to insertion sort for small subarrays.

Answer:
// Exercise23_TukeysNinther.java
package chapter2.section3;

import chapter2.section1.InsertionSort;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.Stopwatch;
import util.ArrayUtil;
import util.ArrayGenerator;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by Rene Argento on 10/03/17.
 */
public class Exercise23_TukeysNinther {

    private static final int SIZE_REQUIRED_FOR_TUKEY_NINTHER = 9;
    private static final int INSERTION_SORT_CUTOFF = 9;

    // Parameters example: 8 1048576
    public static void main(String[] args) {
        int numberOfExperiments = Integer.parseInt(args[0]);
        int initialArraySize = Integer.parseInt(args[1]);

        Map<Integer, Comparable[]> allInputArrays = new HashMap<>();

        int arraySize = initialArraySize;

        for (int i = 0; i < numberOfExperiments; i++) {
            Comparable[] array = ArrayGenerator.generateRandomArrayWith3Values(arraySize);
            allInputArrays.put(i, array);

            arraySize *= 2;
        }

        doExperiment(numberOfExperiments, initialArraySize, allInputArrays);
    }

    private static void doExperiment(int numberOfExperiments, int initialArraySize, Map<Integer, Comparable[]> allInputArrays) {
        StdOut.printf("%13s %16s %38s %52s\n", "Array Size | ", "QuickSort 3-Way |", "QuickSort with fast 3-way partitioning | ",
                "QuickSort w/ fast 3-way partitioning + Tukey Ninther");

        int arraySize = initialArraySize;

        for (int i = 0; i < numberOfExperiments; i++) {
            Comparable[] originalArray = allInputArrays.get(i);
            Comparable[] arrayCopy1 = new Comparable[originalArray.length];
            System.arraycopy(originalArray, 0, arrayCopy1, 0, originalArray.length);
            Comparable[] arrayCopy2 = new Comparable[originalArray.length];
            System.arraycopy(originalArray, 0, arrayCopy2, 0, originalArray.length);

            //QuickSort 3-Way
            Stopwatch quickSort3WaySortTimer = new Stopwatch();

            QuickSort3Way.quickSort3Way(originalArray);

            double quickSort3WayRunningTime = quickSort3WaySortTimer.elapsedTime();

            //QuickSort with fast 3-way partitioning (Bentley-McIlroy)
            Stopwatch quickSortWithFast3WayPartitioning = new Stopwatch();

            Exercise22_Fast3WayPartitioning.quickSortWithFast3WayPartitioning(arrayCopy1);

            double quickSortWithFast3WayPartitioningRunningTime = quickSortWithFast3WayPartitioning.elapsedTime();

            //QuickSort with fast 3-way partitioning (Bentley-McIlroy) + Tukey Ninther
            Stopwatch quickSortWithFast3WayPartitioningTukeyNinther = new Stopwatch();

            quickSortWithFast3WayPartitioningTukeyNinther(arrayCopy2);

            double quickSortWithFast3WayPartitioningTukeyNintherRunningTime = quickSortWithFast3WayPartitioningTukeyNinther.elapsedTime();

            printResults(arraySize, quickSort3WayRunningTime, quickSortWithFast3WayPartitioningRunningTime,
                    quickSortWithFast3WayPartitioningTukeyNintherRunningTime);

            arraySize *= 2;
        }
    }

    private static void quickSortWithFast3WayPartitioningTukeyNinther(Comparable[] array) {
        StdRandom.shuffle(array);
        quickSort(array, 0, array.length - 1);
    }

    @SuppressWarnings("unchecked")
    private static void quickSort(Comparable[] array, int low, int high) {

        if (low >= high) {
            return;
        }

        if (high - low + 1 < INSERTION_SORT_CUTOFF) {
            InsertionSort.insertionSort(array, low, high);
            return;
        }

        int i = low;
        int j = high + 1;

        int p = low;
        int q = high + 1;

        int pivotIndex = getPivotIndex(array, low, high);
        ArrayUtil.exchange(array, low, pivotIndex);
        Comparable pivot = array[low];

        while (true) {

            if (i > low && array[i].compareTo(pivot) == 0) {
                ArrayUtil.exchange(array, ++p, i);
            }
            if (j <= high && array[j].compareTo(pivot) == 0) {
                ArrayUtil.exchange(array, --q, j);
            }

            while (ArrayUtil.less(array[++i], pivot)) {
                if (i == high) {
                    break;
                }
            }

            while (ArrayUtil.less(pivot, array[--j])) {
                if (j == low) {
                    break;
                }
            }

            //pointers cross
            if (i == j && array[i].compareTo(pivot) == 0) {
                ArrayUtil.exchange(array, ++p, i);
            }
            if (i >= j) {
                break;
            }

            ArrayUtil.exchange(array, i, j);
        }

        //Currently:
        // array[low..p] == pivot
        // array[p..i] < pivot
        // array[j..q] > pivot
        // array[q..high] == pivot

        i = j + 1;

        for (int k = low; k <= p; k++) {
            ArrayUtil.exchange(array, k, j--);
        }
        for (int k = high; k >= q; k--) {
            ArrayUtil.exchange(array, k, i++);
        }

        //Now:
        // array[low..j] < pivot
        // array[j..i] == pivot
        // array[i..high] > pivot

        quickSort(array, low, j);
        quickSort(array, i, high);
    }

    //Tukey's ninther
    private static int getPivotIndex(Comparable[] array, int low, int high) {
        int numberOfValues = high - low + 1;

        int eps = numberOfValues / SIZE_REQUIRED_FOR_TUKEY_NINTHER;
        int middle = low + (high - low) / 2;

        int medianIndex1 = getMedianIndex(array, low, low + eps, low + eps + eps);
        int medianIndex2 = getMedianIndex(array, middle - eps, middle, middle + eps);
        int medianIndex3 = getMedianIndex(array, high - eps - eps, high - eps, high);

        return getMedianIndex(array, medianIndex1, medianIndex2, medianIndex3);
    }

    private static int getMedianIndex(Comparable[] array, int index1, int index2, int index3) {
        return ArrayUtil.less(array[index1], array[index2]) ?
                (ArrayUtil.less(array[index2], array[index3]) ? index2 : ArrayUtil.less(array[index1], array[index3])
                        ? index3 : index1) :
                (ArrayUtil.less(array[index1], array[index3]) ? index1 : ArrayUtil.less(array[index2], array[index3]) ? index3 : index2);
    }

    private static void printResults(int arraySize, double quickSort3WayRunningTime, double quickSortWithFast3WayPartitioningRunningTime,
                                     double quickSortWithFast3WayPartitioningTukeyNintherRunningTime) {
        StdOut.printf("%10d %18.1f %40.1f %55.1f\n", arraySize, quickSort3WayRunningTime, quickSortWithFast3WayPartitioningRunningTime,
                quickSortWithFast3WayPartitioningTukeyNintherRunningTime);
    }
}

Additional notes/results:
2.3.23 - Tukey's ninther

The default 3-way partitioning QuickSort had a better running time than both the Bentley-McIlroy 3-way partitioning QuickSort and the Bentley-McIlroy 3-way partitioning QuickSort + Turkey Ninther.
The Bentley-McIlroy 3-way partitioning QuickSort + Turkey Ninther had a better running time than the Bentley-McIlroy 3-way partitioning QuickSort.

Array Size |  QuickSort 3-Way | QuickSort with fast 3-way partitioning |  QuickSort w/ fast 3-way partitioning + Tukey Ninther
   1048576                0.1                                      0.1                                                     0.1
   2097152                0.1                                      0.1                                                     0.1
   4194304                0.2                                      0.2                                                     0.2
   8388608                0.5                                      0.5                                                     0.6
  16777216                1.1                                      1.2                                                     1.2
  33554432                2.4                                      2.6                                                     2.6
  67108864                5.3                                      5.5                                                     5.6
 134217728               11.6                                     12.7                                                    12.1


Question: Samplesort. (W. Frazer and A. McKellar) Implement a quicksort based on using a sample of size 2k - 1. First, sort the sample, then arrange to have the recursive routine partition on the median of the sample and to move the two halves of the rest of the sample to each subarray, such that they can be used in the subarrays, without having to be sorted again. This algorithm is called samplesort.

Answer:
// Exercise24_Samplesort.java
package chapter2.section3;

import chapter2.section1.InsertionSort;
import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.Stopwatch;
import util.ArrayUtil;
import util.ArrayGenerator;

import java.util.Map;

/**
 * Created by Rene Argento on 10/03/17.
 */
// Thanks to ckwastra (https://github.com/ckwastra) for the samplesort implementation.
// https://github.com/reneargento/algorithms-sedgewick-wayne/issues/263
@SuppressWarnings("unchecked")
public class Exercise24_Samplesort {

    private static final int INSERTION_SORT_CUTOFF = 2;

    // Parameters example: 8 131072
    public static void main(String[] args) {
        int numberOfExperiments = Integer.parseInt(args[0]);
        int initialArraySize = Integer.parseInt(args[1]);

        Map<Integer, Comparable[]> allInputArrays = ArrayGenerator.generateAllArrays(numberOfExperiments, initialArraySize, 2);
        doExperiment(numberOfExperiments, initialArraySize, allInputArrays);
    }

    private static <T extends Comparable<T>> void doExperiment(int numberOfExperiments, int initialArraySize,
                                     Map<Integer, Comparable[]> allInputArrays) {
        StdOut.printf("%13s %23s %25s\n", "Array Size | ", "QuickSort Running Time |", "SampleSort Running Time");

        int arraySize = initialArraySize;

        for (int i = 0; i < numberOfExperiments; i++) {
            Comparable<T>[] originalArray = allInputArrays.get(i);
            Comparable<T>[] array = new Comparable[originalArray.length];
            System.arraycopy(originalArray, 0, array, 0, originalArray.length);

            // Default QuickSort
            Stopwatch quickSortTimer = new Stopwatch();
            QuickSort.quickSort(originalArray);
            double quickSortRunningTime = quickSortTimer.elapsedTime();

            // SampleSort
            Stopwatch sampleSortTimer = new Stopwatch();
            sampleSort(array);
            double sampleSortRunningTime = sampleSortTimer.elapsedTime();

            printResults(arraySize, quickSortRunningTime, sampleSortRunningTime);
            arraySize *= 2;
        }
    }

    private static <T extends Comparable<T>> void sampleSort(Comparable<T>[] array) {
        sampleSort(array, array.length);
    }

    private static <T extends Comparable<T>> void sampleSort(Comparable<T>[] array, int size) {
        if (size <= INSERTION_SORT_CUTOFF) {
            InsertionSort.insertionSort(array, 0, size - 1);
            return;
        }

        // Based on Python's (2.23) version of Samplesort
        // numberOfPivots ~= lg(n / ln(n))
        double sizeByLogSize = size / Math.log(size);
        int k = (int) Math.round(Math.log(sizeByLogSize) / Math.log(2));
        int numberOfPivots = (int) Math.pow(2, k) - 1;

        // Pick random samples
        for (int i = 0; i < numberOfPivots; i++) {
            int randomIndex = StdRandom.uniform(size);
            ArrayUtil.exchange(array, i, randomIndex);
        }

        // Recursively sort the sample
        sampleSort(array, numberOfPivots);

        // | 0 1 ... numberOfPivots-1 | numberOfPivots ... n-1 |
        // | <-   sorted sample  ->   | <-    unknown    ->    |
        //                            | lo                  hi |
        sampleSort(array, numberOfPivots, size - 1, numberOfPivots);
    }

    private static <T extends Comparable<T>> void sampleSort(Comparable<T>[] array, int low, int high,
                                                             int numberOfPivots) {
        if (low > high) {
            return;
        }
        if (numberOfPivots == 0) {
            InsertionSort.insertionSort(array, low, high);
            return;
        }

        // Move pivots in-place to always have them on both partitions.
        if (numberOfPivots > 0) {
            // The pivots are to the left of low. Move half to the right end.
            int halfPivots = numberOfPivots / 2;
            for (int i = 0; i < halfPivots; i++) {
                low--;
                ArrayUtil.exchange(array, low, high);
                high--;
            }
        } else {
            // The pivots are to the right of high. Move half to the left end.
            numberOfPivots = -numberOfPivots;
            int halfPivots = (numberOfPivots + 1) / 2;
            for (int i = 0; i < halfPivots; i++) {
                high++;
                ArrayUtil.exchange(array, low, high);
                low++;
            }
        }

        low--;
        int partition = partition(array, low, high);

        int halfPivots;
        int halfPivotsOnLeftPartition;
        if (numberOfPivots % 2 == 0) {
            halfPivots = numberOfPivots / 2;
            halfPivotsOnLeftPartition = halfPivots - 1;
        } else {
            halfPivots = numberOfPivots / 2;
            halfPivotsOnLeftPartition = halfPivots;
        }
        sampleSort(array, low, partition - 1, halfPivotsOnLeftPartition);
        sampleSort(array, partition + 1, high, -halfPivots);
    }

    private static <T extends Comparable<T>> int partition(Comparable<T>[] array, int low, int high) {
        Comparable<T> pivot = array[low];

        int i = low;
        int j = high + 1;

        while (true) {
            while (ArrayUtil.less(array[++i], pivot)) {
                if (i == high) {
                    break;
                }
            }

            while (ArrayUtil.less(pivot, array[--j])) {
                if (j == low) {
                    break;
                }
            }

            if (i >= j) {
                break;
            }

            ArrayUtil.exchange(array, i, j);
        }

        // Place pivot in the right place
        ArrayUtil.exchange(array, low, j);
        return j;
    }

    private static void printResults(int arraySize, double quickSortRunningTime, double sampleSortRunningTime) {
        StdOut.printf("%10d %25.1f %27.1f\n", arraySize, quickSortRunningTime, sampleSortRunningTime);
    }
}

Additional notes/results:
2.3.24 - Samplesort

SampleSort's running time is faster than Quicksort, especially for higher array sizes.

Array Size |  QuickSort Running Time |   SampleSort Running Time
    131072                       0.1                         0.0
    262144                       0.1                         0.1
    524288                       0.2                         0.1
   1048576                       0.4                         0.3
   2097152                       0.9                         0.6
   4194304                       2.2                         1.4
   8388608                       5.3                         3.3
  16777216                      11.9                         7.3


Question: Suppose that the sequence P R I O * R * * I * T * Y * * * Q U E * * * U * E (where a letter means insert and an asterisk means remove the maximum) is applied to an initially empty priority queue. Give the sequence of letters returned by the remove the maximum operations.

Answer:
2.4.1

R R P O T Y I I U Q E U
(E is left on the priority queue)


Question: Criticize the following idea: To implement find the maximum in constant time, why not use a stack or a queue, but keep track of the maximum value inserted so far, then return that value for find the maximum?

Answer:
2.4.2

This idea would not work because it only keeps track of the current maximum. After a remove-the-maximum operation it would not be possible to know which is the next maximum in constant time, requiring a linear operation to find the new maximum.


Question: Provide priority-queue implementations that support insert and remove the maximum, one for each of the following underlying data structures: unordered array, ordered array, unordered linked list, and linked list. Give a table of the worst-case bounds for each operation for each of your four implementations.

Answer:
2.4.3

Data Structure          Method                 Worst-case
Unordered array         Insert                 1
Unordered array         Remove the Maximum     N
Ordered array           Insert                 N
Ordered array           Remove the Maximum     1
Unordered linked list   Insert                 1
Unordered linked list   Remove the Maximum     N
Ordered linked list     Insert                 N
Ordered linked list     Remove the Maximum     1


Question: Is an array that is sorted in decreasing order a max-oriented heap?

Answer:
2.4.4

Yes, an array that is sorted in decreasing order is a max-oriented heap.


Question: Give the heap that results when the keys E A S Y Q U E S T I O N are inserted in that order into an initially empty max-oriented heap.

Answer:
2.4.5

1- E

2- E
  A

3- S
  A E

4- Y
  S E
 A

5-  Y
  S  E
 A Q

6-   Y
  S    U
 A Q  E

7-   Y
  S    U
 A Q  E E

8-   Y
  S    U
 S Q  E E
A

9-    Y
   T      U
 S   Q   E E
A S

10-    Y
    T      U
 S    Q   E E
A S  I

11-    Y
    T      U
 S    Q   E E
A S  I O

12-     Y
    T       U
 S    Q    N E
A S  I O  E


Question: Using the conventions of Exercise 2.4.1, give the sequence of heaps produced when the operations P R I O * R * * I * T * Y * * * Q U E * * * U * E are performed on an initially empty max-oriented heap.

Answer:
2.4.6

Heaps:

1- P

2- R
  P

3- R
  P I

4- R
  P I
 O

5- P
  O I

6- R
  P I
 O

7- P
  O I

8- O
  I

9- O
  I I

10- I
   I

11- T
   I I

12- I
   I

13- Y
   I I

14- I
   I

15- I

16-

17- Q

18- U
   Q

19- U
   Q E

20- Q
   E

21- E

22-

23- U

24-

25- E


Question: The largest item in a heap must appear in position 1, and the second largest must be in position 2 or position 3. Give the list of positions in a heap of size 31 where the kth largest (i) can appear, and (ii) cannot appear, for k=2, 3, 4 (assuming the values to be distinct).

Answer:
2.4.7

Heap-of-size-31 positions

                        1
           2                         3
      4           5             6            7
  8     9     10      11    12     13    14    15
16 17 18 19  20 21  22 23  24 25  26 27 28 29 30 31

Kth largest item  Can appear                         Cannot appear
2                 2,3                                1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
3                 2,3,4,5,6,7                        1,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
4                 2,3,4,5,6,7,8,9,10,11,12,13,14,15  1,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31

Thanks to oeyh (https://github.com/oeyh) for mentioning that the 4th largest item may also appear on positions 2 and 3.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/26


Question: Answer the previous exercise for the kth smallest item.

Answer:
2.4.8

Kth smallest item   Can appear                                                               Cannot appear
2                   16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31                          1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
3                   8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31    1,2,3,4,5,6,7
4                   8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31    1,2,3,4,5,6,7


Question: Draw all of the different heaps that can be made from the five keys A B C D E, then draw all of the different heaps that can be made from the five keys A A A B B.

Answer:
2.4.9

Using A,B,C,D,E keys

1-   E
   D  C
  B A

2-   E
   D  C
  A B

3-   E
   C  D
  B A

4-   E
   C  D
  A B

5-   E
   D  A
  C B

6-   E
   D  A
  B C

7-   E
   D  B
  C A

8-   E
   D  B
  A C

Using A,A,A,B,B keys

1-   B
   B  A
  A A

2-   B
   A  B
  A A


Question: Suppose that we wish to avoid wasting one position in a heap-ordered array pq[], putting the largest value in pq[0], its children in pq[1] and pq[2], and so forth, proceeding in level order. Where are the parents and children of pq[k]?

Answer:
2.4.10

Parent of pq[k]: pq[(k - 1) / 2] (Rounded down)

Children of pq[k]:
Left: pq[k * 2 + 1]
Right: pq[k * 2 + 2]


Question: Describe a way to avoid the j < N test in sink().

Answer:
2.4.13

Changing the line:
while (2*k <= N)

To:
while (2*k < N)

Would guarantee that all indices (2*k + 1) are <= N and with that, the j < N verification would not be necessary.

However, an additional verification would be necessary for the last level of the heap if the node being compared in level n-1 only has a left child.

private void sink(int k) {
    while (2*k < N) {
        int j = 2*k;
        if (less(j, j+1)) j++;
        if (!less(k, j)) break;
        exch(k, j);
        k = j;
    }

    //If we reached the n-1 level of the heap and it only has 1 child (the left child), we need one more verification
    if (2 * k == N) {
        //If the current element is smaller than its child, exchange them
        if (less(k, 2 * k)) {
            exch(k, 2 * k);
        }
    }
}


Question: What is the minimum number of items that must be exchanged during a remove the maximum operation in a heap of size N with no duplicate keys? Give a heap of size 15 for which the minimum is achieved. Answer the same questions for two and three successive remove the maximum operations.

Answer:
2.4.14

The minimum number of items that must be exchanged during a remove the maximum operation in a heap of size N with no duplicate keys is 2.

Heap:
                  100
          99               98
      9       10      97        96
     5 6     7  8   95  94    93  92

For two successive remove the maximum operations the minimum number of exchanges is 5.

Heap:
                  100
          99               98
      9       10      94        97
     5 6     7  8   90  91    93  92

For three successive remove the maximum operations the minimum number of exchanges is 8.

Heap:
                  100
          99               98
      9       10      94        97
     5 6     7  8   90  91    93  92