Question: Which method runs faster for an array in reverse order, selection sort or insertion sort?

Answer:
2.1.7

Selection sort because even though both selection sort and insertion sort will run in quadratic time, selection sort will
only make N exchanges, while insertion sort will make N * N / 2 exchanges.

Thanks to LudekCizinsky (https://github.com/LudekCizinsky), rg9a27 (https://github.com/rg9a27) and
BOTbkcd (https://github.com/BOTbkcd) for correcting the number of exchanges in selection sort.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/194 and
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/211


Question: Suppose that we use insertion sort on a randomly ordered array where elements have only one of three values. Is the running time linear, quadratic, or something in between?

Answer:
2.1.8

Quadratic. Insertion sort's running time is linear when the array is already sorted or all elements are equal.
With three possible values the running time quadratic.


Question: Show, in the style of the example trace with Algorithm 2.3, how shellsort sorts the array E A S Y S H E L L S O R T Q U E S T I O N.

Answer:
2.1.9
				a[]
 h   i   j  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
	    E A S Y S H E L L S  O  R  T  Q  U  E  S  T  I  O  N
13  13  13  E A S Y S H E L L S  O  R  T  Q  U  E  S  T  I  O  N
13  14  14  E A S Y S H E L L S  O  R  T  Q  U  E  S  T  I  O  N
13  15   2  E A E Y S H E L L S  O  R  T  Q  U  S  S  T  I  O  N
13  16   3  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  17  17  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  18  18  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  19  19  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  20  20  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
	    E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   4   4  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   5   5  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   6   6  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   7   3  E A E L S H E S L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   8   4  E A E L L H E S S S  O  R  T  Q  U  S  Y  T  I  O  N
 4   9   9  E A E L L H E S S S  O  R  T  Q  U  S  Y  T  I  O  N
 4  10  10  E A E L L H E S S S  O  R  T  Q  U  S  Y  T  I  O  N
 4  11   7  E A E L L H E R S S  O  S  T  Q  U  S  Y  T  I  O  N
 4  12  12  E A E L L H E R S S  O  S  T  Q  U  S  Y  T  I  O  N
 4  13   9  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  14  14  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  15  15  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  16  16  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  17  17  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  18  10  E A E L L H E R S Q  I  S  T  S  O  S  Y  T  U  O  N
 4  19   7  E A E L L H E O S Q  I  R  T  S  O  S  Y  T  U  S  N
 4  20   8  E A E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
	    E A E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   1   0  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   2   2  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   3   3  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   4   4  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   5   3  A E E H L L E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   6   3  A E E E H L L O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   7   7  A E E E H L L O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   8   7  A E E E H L L N O Q  I  R  S  S  O  S  T  T  U  S  Y
 1   9   9  A E E E H L L N O Q  I  R  S  S  O  S  T  T  U  S  Y
 1  10   5  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  11  11  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  12  12  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  13  13  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  14  10  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  15  15  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  16  16  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  17  17  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  18  18  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  19  16  A E E E H I L L N O  O  Q  R  S  S  S  S  T  T  U  Y
 1  20  20  A E E E H I L L N O  O  Q  R  S  S  S  S  T  T  U  Y
	    A E E E H I L L N O  O  Q  R  S  S  S  S  T  T  U  Y


Question: Why not use selection sort for h-sorting in shellsort?

Answer:
2.1.10
Insertion sort is faster than selection sort for h-sorting because as "h" decreases, the array becomes partially sorted.
Insertion sort makes less comparisons in partially sorted arrays than selection sort.
Also, when h-sorting, eventually h will have an increment value of 1.
Using selection sort with an increment value of 1 would be the same as using the standard selection sort algorithm from the beginning.
This would make the steps with the previous increments to be unnecessary work.

Thanks to jaeheonshim (https://github.com/jaeheonshim) for adding an extra reason not to use selection sort.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/254


Question: Deck sort. Explain how you would put a deck of cards in order by suit (in the order spades, hearts, clubs, diamonds) and by rank within each suit, with the restriction that the cards must be laid out face down in a row, and the only allowed operations are to check the values of two cards and to exchange two cards (keeping them face down).

Answer:
2.1.13 - Deck sort
I would use selection sort, comparing the cards first by suit, and if they have the same suit, by rank.
As we are dealing with physical objects it makes sense to minimize the number of swaps.
With selection sort it may be needed to look at more cards than insertion sort (twice as many in the average case),
but swaps will be required at most 52 times versus at most 676 times.

Thanks to zefrawg (https://github.com/zefrawg) and nedas-dev (https://github.com/nedas-dev) for improving this exercise:
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/198


Question: Dequeue sort. Explain how you would sort a deck of cards, with the restriction that the only allowed operations are to look at the values of the top two cards, to exchange the top two cards, and to move the top card to the bottom of the deck.

Answer:
2.1.14 - Dequeue sort
I would use a variation of bubble sort.

1- I would compare both top cards and, if the top card were bigger than the second card, I would swap them.
2- I would mark the top card, so I could know it was the first card (in this iteration) sent to the bottom of the deck.
3- I would send the top card to the bottom of the deck.
4- I would repeat steps 1 and 3 until the marked card becomes the second card in the deck
5- I would send the top card to the bottom of the deck (and the marked card is now at the top, signaling that a iteration is over)
6- If there were no swaps in this iteration, the deck is sorted. Otherwise, repeat steps 1 to 6.

Nice explanation here:
http://stackoverflow.com/questions/38061140/sort-a-deck-of-cards


Question: Expensive exchange. A clerk at a shipping company is charged with the task of rearranging a number of large crates in order of the time they are to be shipped out. Thus, the cost of compares is very low (just look at the labels) relative to the cost of exchanges (move the crates). The warehouse is nearly full—there is extra space sufficient to hold any one of the crates, but not two. What sorting method should the clerk use?

Answer:
2.1.15 - Expensive exchange

The clerk should use selection sort. Since the cost of compares is low, the N^2 complexity won't be a problem.
And it guarantees a cost of at most N exchanges.


Question: Shellsort best case. What is the best case for shellsort? Justify your answer.

Answer:
2.1.20 - Shellsort best case

Just like insertion sort, the best case for shellsort is when the array is already ordered. This causes every element to
be compared only once in each iteration.
The time complexity in this case is O(n log n).

Good explanation: https://www.toptal.com/developers/sorting-algorithms/shell-sort
http://www.codingeek.com/algorithms/shell-sort-algorithm-explanation-implementation-and-complexity/


Question: Give a trace, in the style of the trace given at the beginning of this section, showing how the keys A E Q S U Y E I N O S T are merged with the abstract in-place merge() method.

Answer:
2.1.1
		a[]
i  min  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    1  E A S Y Q U E S T I  O  N
1    1  A E S Y Q U E S T I  O  N
2    6  A E S Y Q U E S T I  O  N
3    9  A E E Y Q U S S T I  O  N
4   11  A E E I Q U S S T Y  O  N
5   10  A E E I N U S S T Y  O  Q
6   11  A E E I N O S S T Y  U  Q
7    7  A E E I N O Q S T Y  U  S
8   11  A E E I N O Q S T Y  U  S
9   11  A E E I N O Q S S Y  U  T
10  10  A E E I N O Q S S T  U  Y
11  11  A E E I N O Q S S T  U  Y
	A E E I N O Q S S T  U  Y


Question: Give traces, in the style of the trace given with Algorithm 2.4, showing how the keys E A S Y Q U E S T I O N are sorted with top-down mergesort.

Answer:
2.1.2
The maximum number of exchanges involving any particular item during selection sort is N - 1.
This happens when the first item has the highest value in the unsorted array and the other values are sorted.
For example, in the array 4 1 2 3, the element 4 will be swapped N - 1 times.
The average number of exchanges involving an item is exactly 2, because there are exactly N exchanges and N items (and each exchange involves two items).

Reference: https://algs4.cs.princeton.edu/21elementary/


Question: Answer Exercise 2.2.2 for bottom-up mergesort.

Answer:
2.1.3
Array: H G F E D C B A

Thanks to QiotoF (https://github.com/QiotoF) for mentioning a better array solution for this exercise
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/76


Question: Does the abstract in-place merge produce proper output if and only if the two input subarrays are in sorted order? Prove your answer, or provide a counterexample.

Answer:
2.1.4
		a[]
i    j  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    0  E A S Y Q U E S T I  O  N
1    0  A E S Y Q U E S T I  O  N
2    2  A E S Y Q U E S T I  O  N
3    3  A E S Y Q U E S T I  O  N
4    2  A E Q S Y U E S T I  O  N
5    4  A E Q S U Y E S T I  O  N
6    2  A E E Q S U Y S T I  O  N
7    5  A E E Q S S U Y T I  O  N
8    6  A E E Q S S T U Y I  O  N
9    3  A E E I Q S S T U Y  O  N
10   4  A E E I O Q S S T U  Y  N
11   4  A E E I N O Q S S T  U  Y
	A E E I N O Q S S T  U  Y


Question: Give the sequence of subarray sizes in the merges performed by both the top-down and the bottom-up mergesort algorithms, for N = 39.

Answer:
2.1.5

Condition 1: j > 0 -> When the array is reverse ordered
Z Q K D C B A

Condition 2: less(a[j], a[j - 1]) -> When the array is ordered
A B C D E F G


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:
2.1.6

Insertion sort because it will only make one comparison with the previous element (per element) and won't exchange any elements,
running in linear time. Selection sort will exchange each element with itself and will run in quadratic time.

Thanks to glucu (https://github.com/glucu) for correcting the number of exchanges done in selection sort.


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

Answer:
2.1.7

Selection sort because even though both selection sort and insertion sort will run in quadratic time, selection sort will
only make N exchanges, while insertion sort will make N * N / 2 exchanges.

Thanks to LudekCizinsky (https://github.com/LudekCizinsky), rg9a27 (https://github.com/rg9a27) and
BOTbkcd (https://github.com/BOTbkcd) for correcting the number of exchanges in selection sort.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/194 and
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/211


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.1.8

Quadratic. Insertion sort's running time is linear when the array is already sorted or all elements are equal.
With three possible values the running time quadratic.


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:
2.1.9
				a[]
 h   i   j  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
	    E A S Y S H E L L S  O  R  T  Q  U  E  S  T  I  O  N
13  13  13  E A S Y S H E L L S  O  R  T  Q  U  E  S  T  I  O  N
13  14  14  E A S Y S H E L L S  O  R  T  Q  U  E  S  T  I  O  N
13  15   2  E A E Y S H E L L S  O  R  T  Q  U  S  S  T  I  O  N
13  16   3  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  17  17  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  18  18  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  19  19  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  20  20  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
	    E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   4   4  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   5   5  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   6   6  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   7   3  E A E L S H E S L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   8   4  E A E L L H E S S S  O  R  T  Q  U  S  Y  T  I  O  N
 4   9   9  E A E L L H E S S S  O  R  T  Q  U  S  Y  T  I  O  N
 4  10  10  E A E L L H E S S S  O  R  T  Q  U  S  Y  T  I  O  N
 4  11   7  E A E L L H E R S S  O  S  T  Q  U  S  Y  T  I  O  N
 4  12  12  E A E L L H E R S S  O  S  T  Q  U  S  Y  T  I  O  N
 4  13   9  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  14  14  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  15  15  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  16  16  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  17  17  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  18  10  E A E L L H E R S Q  I  S  T  S  O  S  Y  T  U  O  N
 4  19   7  E A E L L H E O S Q  I  R  T  S  O  S  Y  T  U  S  N
 4  20   8  E A E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
	    E A E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   1   0  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   2   2  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   3   3  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   4   4  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   5   3  A E E H L L E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   6   3  A E E E H L L O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   7   7  A E E E H L L O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   8   7  A E E E H L L N O Q  I  R  S  S  O  S  T  T  U  S  Y
 1   9   9  A E E E H L L N O Q  I  R  S  S  O  S  T  T  U  S  Y
 1  10   5  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  11  11  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  12  12  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  13  13  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  14  10  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  15  15  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  16  16  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  17  17  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  18  18  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  19  16  A E E E H I L L N O  O  Q  R  S  S  S  S  T  T  U  Y
 1  20  20  A E E E H I L L N O  O  Q  R  S  S  S  S  T  T  U  Y
	    A E E E H I L L N O  O  Q  R  S  S  S  S  T  T  U  Y


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:
2.1.10
Insertion sort is faster than selection sort for h-sorting because as "h" decreases, the array becomes partially sorted.
Insertion sort makes less comparisons in partially sorted arrays than selection sort.
Also, when h-sorting, eventually h will have an increment value of 1.
Using selection sort with an increment value of 1 would be the same as using the standard selection sort algorithm from the beginning.
This would make the steps with the previous increments to be unnecessary work.

Thanks to jaeheonshim (https://github.com/jaeheonshim) for adding an extra reason not to use selection sort.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/254


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.1.13 - Deck sort
I would use selection sort, comparing the cards first by suit, and if they have the same suit, by rank.
As we are dealing with physical objects it makes sense to minimize the number of swaps.
With selection sort it may be needed to look at more cards than insertion sort (twice as many in the average case),
but swaps will be required at most 52 times versus at most 676 times.

Thanks to zefrawg (https://github.com/zefrawg) and nedas-dev (https://github.com/nedas-dev) for improving this exercise:
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/198


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:
2.1.14 - Dequeue sort
I would use a variation of bubble sort.

1- I would compare both top cards and, if the top card were bigger than the second card, I would swap them.
2- I would mark the top card, so I could know it was the first card (in this iteration) sent to the bottom of the deck.
3- I would send the top card to the bottom of the deck.
4- I would repeat steps 1 and 3 until the marked card becomes the second card in the deck
5- I would send the top card to the bottom of the deck (and the marked card is now at the top, signaling that a iteration is over)
6- If there were no swaps in this iteration, the deck is sorted. Otherwise, repeat steps 1 to 6.

Nice explanation here:
http://stackoverflow.com/questions/38061140/sort-a-deck-of-cards


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:
2.1.15 - Expensive exchange

The clerk should use selection sort. Since the cost of compares is low, the N^2 complexity won't be a problem.
And it guarantees a cost of at most N exchanges.


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:
2.1.20 - Shellsort best case

Just like insertion sort, the best case for shellsort is when the array is already ordered. This causes every element to
be compared only once in each iteration.
The time complexity in this case is O(n log n).

Good explanation: https://www.toptal.com/developers/sorting-algorithms/shell-sort
http://www.codingeek.com/algorithms/shell-sort-algorithm-explanation-implementation-and-complexity/


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.1.1
		a[]
i  min  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    1  E A S Y Q U E S T I  O  N
1    1  A E S Y Q U E S T I  O  N
2    6  A E S Y Q U E S T I  O  N
3    9  A E E Y Q U S S T I  O  N
4   11  A E E I Q U S S T Y  O  N
5   10  A E E I N U S S T Y  O  Q
6   11  A E E I N O S S T Y  U  Q
7    7  A E E I N O Q S T Y  U  S
8   11  A E E I N O Q S T Y  U  S
9   11  A E E I N O Q S S Y  U  T
10  10  A E E I N O Q S S T  U  Y
11  11  A E E I N O Q S S T  U  Y
	A E E I N O Q S S T  U  Y


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.1.2
The maximum number of exchanges involving any particular item during selection sort is N - 1.
This happens when the first item has the highest value in the unsorted array and the other values are sorted.
For example, in the array 4 1 2 3, the element 4 will be swapped N - 1 times.
The average number of exchanges involving an item is exactly 2, because there are exactly N exchanges and N items (and each exchange involves two items).

Reference: https://algs4.cs.princeton.edu/21elementary/


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.1.3
Array: H G F E D C B A

Thanks to QiotoF (https://github.com/QiotoF) for mentioning a better array solution for this exercise
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/76


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.1.4
		a[]
i    j  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    0  E A S Y Q U E S T I  O  N
1    0  A E S Y Q U E S T I  O  N
2    2  A E S Y Q U E S T I  O  N
3    3  A E S Y Q U E S T I  O  N
4    2  A E Q S Y U E S T I  O  N
5    4  A E Q S U Y E S T I  O  N
6    2  A E E Q S U Y S T I  O  N
7    5  A E E Q S S U Y T I  O  N
8    6  A E E Q S S T U Y I  O  N
9    3  A E E I Q S S T U Y  O  N
10   4  A E E I O Q S S T U  Y  N
11   4  A E E I N O Q S S T  U  Y
	A E E I N O Q S S T  U  Y


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

Answer:
2.1.5

Condition 1: j > 0 -> When the array is reverse ordered
Z Q K D C B A

Condition 2: less(a[j], a[j - 1]) -> When the array is ordered
A B C D E F G


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:
2.1.6

Insertion sort because it will only make one comparison with the previous element (per element) and won't exchange any elements,
running in linear time. Selection sort will exchange each element with itself and will run in quadratic time.

Thanks to glucu (https://github.com/glucu) for correcting the number of exchanges done in selection sort.


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.1.7

Selection sort because even though both selection sort and insertion sort will run in quadratic time, selection sort will
only make N exchanges, while insertion sort will make N * N / 2 exchanges.

Thanks to LudekCizinsky (https://github.com/LudekCizinsky), rg9a27 (https://github.com/rg9a27) and
BOTbkcd (https://github.com/BOTbkcd) for correcting the number of exchanges in selection sort.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/194 and
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/211


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

Answer:
2.1.8

Quadratic. Insertion sort's running time is linear when the array is already sorted or all elements are equal.
With three possible values the running time quadratic.


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.1.9
				a[]
 h   i   j  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
	    E A S Y S H E L L S  O  R  T  Q  U  E  S  T  I  O  N
13  13  13  E A S Y S H E L L S  O  R  T  Q  U  E  S  T  I  O  N
13  14  14  E A S Y S H E L L S  O  R  T  Q  U  E  S  T  I  O  N
13  15   2  E A E Y S H E L L S  O  R  T  Q  U  S  S  T  I  O  N
13  16   3  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  17  17  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  18  18  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  19  19  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  20  20  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
	    E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   4   4  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   5   5  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   6   6  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   7   3  E A E L S H E S L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   8   4  E A E L L H E S S S  O  R  T  Q  U  S  Y  T  I  O  N
 4   9   9  E A E L L H E S S S  O  R  T  Q  U  S  Y  T  I  O  N
 4  10  10  E A E L L H E S S S  O  R  T  Q  U  S  Y  T  I  O  N
 4  11   7  E A E L L H E R S S  O  S  T  Q  U  S  Y  T  I  O  N
 4  12  12  E A E L L H E R S S  O  S  T  Q  U  S  Y  T  I  O  N
 4  13   9  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  14  14  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  15  15  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  16  16  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  17  17  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  18  10  E A E L L H E R S Q  I  S  T  S  O  S  Y  T  U  O  N
 4  19   7  E A E L L H E O S Q  I  R  T  S  O  S  Y  T  U  S  N
 4  20   8  E A E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
	    E A E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   1   0  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   2   2  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   3   3  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   4   4  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   5   3  A E E H L L E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   6   3  A E E E H L L O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   7   7  A E E E H L L O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   8   7  A E E E H L L N O Q  I  R  S  S  O  S  T  T  U  S  Y
 1   9   9  A E E E H L L N O Q  I  R  S  S  O  S  T  T  U  S  Y
 1  10   5  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  11  11  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  12  12  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  13  13  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  14  10  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  15  15  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  16  16  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  17  17  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  18  18  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  19  16  A E E E H I L L N O  O  Q  R  S  S  S  S  T  T  U  Y
 1  20  20  A E E E H I L L N O  O  Q  R  S  S  S  S  T  T  U  Y
	    A E E E H I L L N O  O  Q  R  S  S  S  S  T  T  U  Y


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.1.10
Insertion sort is faster than selection sort for h-sorting because as "h" decreases, the array becomes partially sorted.
Insertion sort makes less comparisons in partially sorted arrays than selection sort.
Also, when h-sorting, eventually h will have an increment value of 1.
Using selection sort with an increment value of 1 would be the same as using the standard selection sort algorithm from the beginning.
This would make the steps with the previous increments to be unnecessary work.

Thanks to jaeheonshim (https://github.com/jaeheonshim) for adding an extra reason not to use selection sort.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/254


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.1.13 - Deck sort
I would use selection sort, comparing the cards first by suit, and if they have the same suit, by rank.
As we are dealing with physical objects it makes sense to minimize the number of swaps.
With selection sort it may be needed to look at more cards than insertion sort (twice as many in the average case),
but swaps will be required at most 52 times versus at most 676 times.

Thanks to zefrawg (https://github.com/zefrawg) and nedas-dev (https://github.com/nedas-dev) for improving this exercise:
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/198


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). Then use this result to prove Proposition K.

Answer:
2.1.14 - Dequeue sort
I would use a variation of bubble sort.

1- I would compare both top cards and, if the top card were bigger than the second card, I would swap them.
2- I would mark the top card, so I could know it was the first card (in this iteration) sent to the bottom of the deck.
3- I would send the top card to the bottom of the deck.
4- I would repeat steps 1 and 3 until the marked card becomes the second card in the deck
5- I would send the top card to the bottom of the deck (and the marked card is now at the top, signaling that a iteration is over)
6- If there were no swaps in this iteration, the deck is sorted. Otherwise, repeat steps 1 to 6.

Nice explanation here:
http://stackoverflow.com/questions/38061140/sort-a-deck-of-cards


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.1.15 - Expensive exchange

The clerk should use selection sort. Since the cost of compares is low, the N^2 complexity won't be a problem.
And it guarantees a cost of at most N exchanges.


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:
2.1.20 - Shellsort best case

Just like insertion sort, the best case for shellsort is when the array is already ordered. This causes every element to
be compared only once in each iteration.
The time complexity in this case is O(n log n).

Good explanation: https://www.toptal.com/developers/sorting-algorithms/shell-sort
http://www.codingeek.com/algorithms/shell-sort-algorithm-explanation-implementation-and-complexity/


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:
2.1.23 - Deck sort

They separate all cards by suit, making the swaps in order to keep cards in the same suit next to each other (dividing the row in 4 areas).
Then, in each suit, they sort the cards by rank using selection sort.
In the second step (once suits are sorted), some of them move the unsorted smaller ranks near to the front while searching for the next smallest rank.


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:
2.1.24 - Insertion sort with sentinel

For 100000 random doubles
 Insertion Sort default is 1.1 times faster than Insertion Sort with a sentinel

Insertion Sort default is slightly faster than Insertion Sort with a sentinel.


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.1.1
		a[]
i  min  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    1  E A S Y Q U E S T I  O  N
1    1  A E S Y Q U E S T I  O  N
2    6  A E S Y Q U E S T I  O  N
3    9  A E E Y Q U S S T I  O  N
4   11  A E E I Q U S S T Y  O  N
5   10  A E E I N U S S T Y  O  Q
6   11  A E E I N O S S T Y  U  Q
7    7  A E E I N O Q S T Y  U  S
8   11  A E E I N O Q S T Y  U  S
9   11  A E E I N O Q S S Y  U  T
10  10  A E E I N O Q S S T  U  Y
11  11  A E E I N O Q S S T  U  Y
	A E E I N O Q S S T  U  Y


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.1.2
The maximum number of exchanges involving any particular item during selection sort is N - 1.
This happens when the first item has the highest value in the unsorted array and the other values are sorted.
For example, in the array 4 1 2 3, the element 4 will be swapped N - 1 times.
The average number of exchanges involving an item is exactly 2, because there are exactly N exchanges and N items (and each exchange involves two items).

Reference: https://algs4.cs.princeton.edu/21elementary/


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.1.3
Array: H G F E D C B A

Thanks to QiotoF (https://github.com/QiotoF) for mentioning a better array solution for this exercise
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/76


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

Answer:
2.1.4
		a[]
i    j  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    0  E A S Y Q U E S T I  O  N
1    0  A E S Y Q U E S T I  O  N
2    2  A E S Y Q U E S T I  O  N
3    3  A E S Y Q U E S T I  O  N
4    2  A E Q S Y U E S T I  O  N
5    4  A E Q S U Y E S T I  O  N
6    2  A E E Q S U Y S T I  O  N
7    5  A E E Q S S U Y T I  O  N
8    6  A E E Q S S T U Y I  O  N
9    3  A E E I Q S S T U Y  O  N
10   4  A E E I O Q S S T U  Y  N
11   4  A E E I N O Q S S T  U  Y
	A E E I N O Q S S T  U  Y


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.1.5

Condition 1: j > 0 -> When the array is reverse ordered
Z Q K D C B A

Condition 2: less(a[j], a[j - 1]) -> When the array is ordered
A B C D E F G


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.1.6

Insertion sort because it will only make one comparison with the previous element (per element) and won't exchange any elements,
running in linear time. Selection sort will exchange each element with itself and will run in quadratic time.

Thanks to glucu (https://github.com/glucu) for correcting the number of exchanges done in selection sort.


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.1.7

Selection sort because even though both selection sort and insertion sort will run in quadratic time, selection sort will
only make N exchanges, while insertion sort will make N * N / 2 exchanges.

Thanks to LudekCizinsky (https://github.com/LudekCizinsky), rg9a27 (https://github.com/rg9a27) and
BOTbkcd (https://github.com/BOTbkcd) for correcting the number of exchanges in selection sort.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/194 and
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/211


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

Answer:
2.1.8

Quadratic. Insertion sort's running time is linear when the array is already sorted or all elements are equal.
With three possible values the running time quadratic.


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.1.9
				a[]
 h   i   j  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
	    E A S Y S H E L L S  O  R  T  Q  U  E  S  T  I  O  N
13  13  13  E A S Y S H E L L S  O  R  T  Q  U  E  S  T  I  O  N
13  14  14  E A S Y S H E L L S  O  R  T  Q  U  E  S  T  I  O  N
13  15   2  E A E Y S H E L L S  O  R  T  Q  U  S  S  T  I  O  N
13  16   3  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  17  17  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  18  18  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  19  19  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  20  20  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
	    E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   4   4  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   5   5  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   6   6  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   7   3  E A E L S H E S L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   8   4  E A E L L H E S S S  O  R  T  Q  U  S  Y  T  I  O  N
 4   9   9  E A E L L H E S S S  O  R  T  Q  U  S  Y  T  I  O  N
 4  10  10  E A E L L H E S S S  O  R  T  Q  U  S  Y  T  I  O  N
 4  11   7  E A E L L H E R S S  O  S  T  Q  U  S  Y  T  I  O  N
 4  12  12  E A E L L H E R S S  O  S  T  Q  U  S  Y  T  I  O  N
 4  13   9  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  14  14  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  15  15  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  16  16  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  17  17  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  18  10  E A E L L H E R S Q  I  S  T  S  O  S  Y  T  U  O  N
 4  19   7  E A E L L H E O S Q  I  R  T  S  O  S  Y  T  U  S  N
 4  20   8  E A E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
	    E A E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   1   0  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   2   2  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   3   3  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   4   4  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   5   3  A E E H L L E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   6   3  A E E E H L L O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   7   7  A E E E H L L O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   8   7  A E E E H L L N O Q  I  R  S  S  O  S  T  T  U  S  Y
 1   9   9  A E E E H L L N O Q  I  R  S  S  O  S  T  T  U  S  Y
 1  10   5  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  11  11  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  12  12  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  13  13  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  14  10  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  15  15  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  16  16  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  17  17  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  18  18  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  19  16  A E E E H I L L N O  O  Q  R  S  S  S  S  T  T  U  Y
 1  20  20  A E E E H I L L N O  O  Q  R  S  S  S  S  T  T  U  Y
	    A E E E H I L L N O  O  Q  R  S  S  S  S  T  T  U  Y


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.1.10
Insertion sort is faster than selection sort for h-sorting because as "h" decreases, the array becomes partially sorted.
Insertion sort makes less comparisons in partially sorted arrays than selection sort.
Also, when h-sorting, eventually h will have an increment value of 1.
Using selection sort with an increment value of 1 would be the same as using the standard selection sort algorithm from the beginning.
This would make the steps with the previous increments to be unnecessary work.

Thanks to jaeheonshim (https://github.com/jaeheonshim) for adding an extra reason not to use selection sort.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/254


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

Answer:
2.1.13 - Deck sort
I would use selection sort, comparing the cards first by suit, and if they have the same suit, by rank.
As we are dealing with physical objects it makes sense to minimize the number of swaps.
With selection sort it may be needed to look at more cards than insertion sort (twice as many in the average case),
but swaps will be required at most 52 times versus at most 676 times.

Thanks to zefrawg (https://github.com/zefrawg) and nedas-dev (https://github.com/nedas-dev) for improving this exercise:
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/198


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.1.14 - Dequeue sort
I would use a variation of bubble sort.

1- I would compare both top cards and, if the top card were bigger than the second card, I would swap them.
2- I would mark the top card, so I could know it was the first card (in this iteration) sent to the bottom of the deck.
3- I would send the top card to the bottom of the deck.
4- I would repeat steps 1 and 3 until the marked card becomes the second card in the deck
5- I would send the top card to the bottom of the deck (and the marked card is now at the top, signaling that a iteration is over)
6- If there were no swaps in this iteration, the deck is sorted. Otherwise, repeat steps 1 to 6.

Nice explanation here:
http://stackoverflow.com/questions/38061140/sort-a-deck-of-cards


Question: Design a linear-time certification algorithm to check whether an array pq[] is a min-oriented heap.

Answer:
2.1.15 - Expensive exchange

The clerk should use selection sort. Since the cost of compares is low, the N^2 complexity won't be a problem.
And it guarantees a cost of at most N exchanges.


Question: Prove that sink-based heap construction uses fewer than 2N compares and fewer than N exchanges.

Answer:
2.1.20 - Shellsort best case

Just like insertion sort, the best case for shellsort is when the array is already ordered. This causes every element to
be compared only once in each iteration.
The time complexity in this case is O(n log n).

Good explanation: https://www.toptal.com/developers/sorting-algorithms/shell-sort
http://www.codingeek.com/algorithms/shell-sort-algorithm-explanation-implementation-and-complexity/


Question: Multiway heaps. Considering the cost of compares only, and assuming that it takes t compares to find the largest of t items, find the value of t that minimizes the coefficient of N lg N in the compare count when a t-ary heap is used in heapsort. First, assume a straightforward generalization of sink(); then, assume that Floyd’s method can save one compare in the inner loop.

Answer:
2.1.23 - Deck sort

They separate all cards by suit, making the swaps in order to keep cards in the same suit next to each other (dividing the row in 4 areas).
Then, in each suit, they sort the cards by rank using selection sort.
In the second step (once suits are sorted), some of them move the unsorted smaller ranks near to the front while searching for the next smallest rank.


Question: Priority queue with explicit links. Implement a priority queue using a heap-ordered binary tree, but use a triply linked structure instead of an array. You will need three links per node: two to traverse down the tree and one to traverse up the tree. Your implementation should guarantee logarithmic running time per operation, even if no maximum priority-queue size is known ahead of time.

Answer:
2.1.24 - Insertion sort with sentinel

For 100000 random doubles
 Insertion Sort default is 1.1 times faster than Insertion Sort with a sentinel

Insertion Sort default is slightly faster than Insertion Sort with a sentinel.


Question: Computational number theory. Write a program CubeSum.java that prints out all integers of the form a^3 + b^3 where a and b are integers between 0 and N in sorted order, without using excessive space. That is, instead of computing an array of the N^2 sums and sorting them, build a minimum-oriented priority queue, initially containing (0^3, 0, 0), (1^3, 1, 0), (2^3, 2, 0), . . . , (N^3, N, 0). Then, while the priority queue is nonempty, remove the smallest item(i^3 + j^3, i, j), print it, and then, if j < N, insert the item (i^3 + (j+1)^3, i, j+1). Use this program to find all distinct integers a, b, c, and d between 0 and 10^6 such that a^3 + b^3 = c^3 + d^3.

Answer:
2.1.25 - Insertion sort without exchanges

For 100000 random doubles
 Insertion Sort default is 0.7 times faster than Insertion Sort without exchanges

Insertion Sort without exchanges is faster than Insertion Sort default.


Question: Heap without exchanges. Because the exch() primitive is used in the sink() and swim() operations, the items are loaded and stored twice as often as necessary. Give more efficient implementations that avoid this inefficiency, a la insertion sort (see Exercise 2.1.25).

Answer:
2.1.26 - Primitive types

For 100000 random doubles
 Insertion Sort with primitives is 2.0 times faster than Insertion Sort with objects

Insertion Sort with primitives is faster than Insertion Sor with objects.


Question: Find the minimum. Add a min() method to MaxPQ. Your implementation should use constant time and constant extra space.

Answer:
2.1.27 - Shellsort is subquadratic

For a total of 11 experiments with 128, 256, ..., 262,144 values

Shell Sort is 343.0 times faster than Selection Sort
Shell Sort is 338.8 times faster than Insertion Sort


Question: Selection filter. Write a TopM client that reads points (x, y, z) from standard input, takes a value M from the command line, and prints the M points that are closest to the origin in Euclidean distance. Estimate the running time of your client for N = 10^8 and M = 10^4.

Answer:
2.1.28 - Equal keys

From the book we know that:
Proposition A. Selection sort uses ~(N^2 / 2) compares and N exchanges to sort an array of length N.
Proposition B. Insertion sort uses ~(N^2 / 4) compares and ~(N^2 / 4) exchanges to sort a randomly ordered array of
length N with distinct keys, on the average. The worst case is ~(N^2 / 2) compares and ~(N^2 / 2) exchanges and the best
case is N - 1 compares and 0 exchanges.

Thus the running time of selection sort is bound by O(N^2 / 2) and insertion sort averages on O(N^2 / 2)
(this is because ~(N^2 / 4) compares + ~(N^2 / 4) exchanges = ~(N^2 / 4)).

For arrays with 2 key values (assuming value 1 and value 2) of equal probability:
* Selection sort: it still needs to scan N - K elements to sort the Kth element.
  So its asymptotic running time remains the same O(N^2 / 2).
* Insertion sort: when sorting the (K + 1)th element, there are already K / 2 ones and K / 2 twos sorted.
  Thus the (random variable) expected value of the running time for sorting the (K + 1)th element is:
  0.5 * 1 + 0.5 * K
  Thus the total running time for K = 0, 1, 2, ..., N is:
  0.5 * N + ((N + 1) * N / 2) * 0.5 = 3N/4 + (N ^ 2) / 4 ~= O(N^2 / 4)
  Comparing O(N^2 / 4) against O(N^2 / 2) we can make the hypothesis that the running time of insertion sort with
  2 key values is half of that for random values.

Hypothesis:
1- Selection sort will take the same time for both arrays with different values and arrays with only 2 possible values.
2- Insertion sort will take half the same for arrays with only 2 possible values than for arrays with different values.

Validation:

Selection Sort
For an array of size 128:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 256:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 512:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 1024:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 2048:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 4096:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 8192:
Time for an array with any values: 0.1
Time for an array with 2 values: 0.1

For an array of size 16384:
Time for an array with any values: 0.2
Time for an array with 2 values: 0.2

For an array of size 32768:
Time for an array with any values: 1.0
Time for an array with 2 values: 0.7

For an array of size 65536:
Time for an array with any values: 4.4
Time for an array with 2 values: 3.0

For an array of size 131072:
Time for an array with any values: 20.9
Time for an array with 2 values: 11.7

Insertion Sort
For an array of size 128:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 256:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 512:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 1024:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 2048:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 4096:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 8192:
Time for an array with any values: 0.1
Time for an array with 2 values: 0.0

For an array of size 16384:
Time for an array with any values: 0.2
Time for an array with 2 values: 0.1

For an array of size 32768:
Time for an array with any values: 1.0
Time for an array with 2 values: 0.4

For an array of size 65536:
Time for an array with any values: 4.3
Time for an array with 2 values: 1.5

For an array of size 131072:
Time for an array with any values: 18.9
Time for an array with 2 values: 6.3

--------
Result:
1- Selection sort is faster for arrays with only 2 possible values than for arrays with different values.
2- Insertion sort is a lot faster (about a third of the time) for arrays with only 2 possible values than for arrays with different values.

Also, insertion sort is faster than selection sort for sorting arrays with only 2 possible values.

Thanks to faame (https://github.com/faame) for improving the analysis.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/216


Question: Min/max priority queue. Design a data type that supports the following operations: insert, delete the maximum, and delete the minimum (all in logarithmic time); and find the maximum and find the minimum (both in constant time). Hint: Use two heaps.

Answer:
2.1.29 - Shellsort increments

Sedgewicks's sequence is faster than the 3N + 1 sequence.

Experiments:

For an array of size 32768:
3N + 1 sequence: 0.0
Sedgewicks's sequence: 0.0

For an array of size 65536:
3N + 1 sequence: 0.0
Sedgewicks's sequence: 0.0

For an array of size 131072:
3N + 1 sequence: 0.1
Sedgewicks's sequence: 0.0

For an array of size 262144:
3N + 1 sequence: 0.1
Sedgewicks's sequence: 0.1

For an array of size 524288:
3N + 1 sequence: 0.3
Sedgewicks's sequence: 0.3

For an array of size 1048576:
3N + 1 sequence: 1.0
Sedgewicks's sequence: 0.7

For an array of size 2097152:
3N + 1 sequence: 2.5
Sedgewicks's sequence: 1.8

For an array of size 4194304:
3N + 1 sequence: 7.2
Sedgewicks's sequence: 4.5

For an array of size 8388608:
3N + 1 sequence: 18.4
Sedgewicks's sequence: 11.2

For an array of size 16777216:
3N + 1 sequence: 46.0
Sedgewicks's sequence: 26.6


Question: Dynamic median-finding. Design a data type that supports insert in logarithmic time, find the median in constant time, and delete the median in logarithmic time. Hint: Use a min-heap and a max-heap.

Answer:
2.1.30 - Geometric increments

Best 1 tValue: 2.10
Best 1 sequence:
1 2 4 9 19 40 85 180 378 794 1667 3502 7355 15447 32439 68122 143056 300419 630880

Best 2 tValue: 2.40
Best 2 sequence:
1 2 5 13 33 79 191 458 1100 2641 6340 15216 36520 87648 210357 504857

Best 3 tValue: 2.20
Best 3 sequence:
1 2 4 10 23 51 113 249 548 1207 2655 5843 12855 28281 62218 136880 301136 662499


Question: Fast insert. Develop a compare-based implementation of the MinPQ API such that insert uses ~log log N compares and delete the minimum uses ~2 log N compares. Hint: Use binary search on parent pointers to find the ancestor in swim().

Answer:
2.1.31 - Doubling test

Selection sort and insertion sort are quadratic for random inputs.

     N  Predicted Time    Time Ratio

Selection sort
  2000             0.0     0.0   0.6
  4000             0.0     0.0   2.3
  8000             0.1     0.1   3.8
 16000             0.2     0.3   4.7
 32000             1.0     1.2   4.9
 64000             4.9     5.1   4.1
128000            20.3    20.6   4.1
256000            82.2   124.6   6.1

Insertion sort
  2000             0.0     0.0   2.4
  4000             0.1     0.0   0.9
  8000             0.1     0.1   4.1
 16000             0.2     0.3   4.3
 32000             1.1     1.1   4.3
 64000             4.6     4.9   4.3
128000            19.6    22.8   4.7
256000            91.3   125.7   5.5

Hypothesis: Shell sort is sub quadratic for random inputs. It's worse case (with the 3N + 1 increment sequence) is N ^ 3/2.

Shell sort
  2000             0.0     0.0   0.5
  4000             0.0     0.0   1.0
  8000             0.0     0.0   2.0
 16000             0.0     0.0   1.0
 32000             0.0     0.0   2.0
 64000             0.0     0.0   2.5
128000             0.1     0.1   2.5
256000             0.1     0.1   2.4
512000             0.3     0.3   2.8
1024000             1.0     1.0   2.8
2048000             2.7     2.4   2.5
4096000             6.8     6.4   2.7
8192000            18.1    18.7   2.9
16384000            52.7    44.4   2.4
32768000           125.3   123.6   2.8
65536000           348.7   304.6   2.5

Hypothesis validated.


Question: Index priority-queue implementation (additional operations). Add minIndex(), change(), and delete() to your implementation of Exercise 2.4.33.

Answer:
2.1.34 - Corner cases

As expected:
For ordered arrays insertion sort runs in linear time, and is faster than selection sort.
For reverse ordered arrays insertion sort runs much slower because it has to swap all values until the beginning of the array.
For same keys, just like with ordered arrays, insertion sort runs in linear time.
For 2 distinct values, insertion sort has to do less swaps, running faster than selection sort.
For size 1 and size 0 arrays all sorts run fast.
Shell sort is faster than selection sort and insertion sort in all cases.

      Sort Type      Array Length     Time
ORDERED ARRAY
      SELECTION             10000     0.05
      INSERTION             10000     0.00
          SHELL             10000     0.00
      SELECTION             20000     0.18
      INSERTION             20000     0.00
          SHELL             20000     0.00
      SELECTION             40000     0.81
      INSERTION             40000     0.00
          SHELL             40000     0.00
      SELECTION             80000     2.99
      INSERTION             80000     0.00
          SHELL             80000     0.00
      SELECTION            160000    12.04
      INSERTION            160000     0.00
          SHELL            160000     0.00

REVERSE ORDERED ARRAY
      SELECTION             10000     0.10
      INSERTION             10000     0.25
          SHELL             10000     0.00
      SELECTION             20000     0.33
      INSERTION             20000     0.62
          SHELL             20000     0.00
      SELECTION             40000     1.15
      INSERTION             40000     2.45
          SHELL             40000     0.00
      SELECTION             80000     4.85
      INSERTION             80000    10.65
          SHELL             80000     0.01
      SELECTION            160000    17.66
      INSERTION            160000    42.76
          SHELL            160000     0.01

SAME KEYS ARRAY
      SELECTION             10000     0.09
      INSERTION             10000     0.00
          SHELL             10000     0.00
      SELECTION             20000     0.29
      INSERTION             20000     0.00
          SHELL             20000     0.00
      SELECTION             40000     1.16
      INSERTION             40000     0.00
          SHELL             40000     0.00
      SELECTION             80000     4.64
      INSERTION             80000     0.00
          SHELL             80000     0.00
      SELECTION            160000    17.01
      INSERTION            160000     0.00
          SHELL            160000     0.00

TWO VALUES ARRAY
      SELECTION             10000     0.07
      INSERTION             10000     0.04
          SHELL             10000     0.00
      SELECTION             20000     0.29
      INSERTION             20000     0.17
          SHELL             20000     0.00
      SELECTION             40000     1.07
      INSERTION             40000     0.65
          SHELL             40000     0.00
      SELECTION             80000     4.68
      INSERTION             80000     2.66
          SHELL             80000     0.00
      SELECTION            160000    18.59
      INSERTION            160000    10.46
          SHELL            160000     0.00

SIZE 1 ARRAY
      SELECTION                 1     0.00
      INSERTION                 1     0.00
          SHELL                 1     0.00

SIZE 0 ARRAY
      SELECTION                 0     0.00
      INSERTION                 0     0.00
          SHELL                 0     0.00


Question: Sampling from a discrete probability distribution. Write a class Sample with a constructor that takes an array p[] of double values as argument and supports the following two operations: random()—return an index i with probability p[i]/T (where T is the sum of the numbers in p[])—and change(i, v)—change the value of p[i] to v. Hint: Use a complete binary tree where each node has implied weight p[i]. Store in each node the cumulative weight of all the nodes in its subtree. To generate a random index, pick a random number between 0 and T and use the cumulative weights to determine which branch of the subtree to explore. When updating p[i], change all of the weights of the nodes on the path from the root to i. Avoid explicit pointers, as we do for heaps.

Answer:
2.1.35 - Nonuniform distributions

Hypotheses:
Selection sort will run with the same speed in all distributions.
Insertion sort will run faster than selection sort for Gaussian and Discrete distributions, but with a similar speed for Poisson and Geometric distributions.
Shell sort will run faster than selection sort and insertion sort for all distributions.

After testing the hypotheses:
Selection sort ran faster for Gaussian and Discrete distributions than for Poisson and Geometric distributions.
Insertion sort ran faster than selection sort for all distributions.
Shell sort ran faster than selection sort and insertion sort for all distributions.

      Sort Type      Array Length     Time
GAUSSIAN DISTRIBUTION
      SELECTION             10000     0.13
      INSERTION             10000     0.10
          SHELL             10000     0.01
      SELECTION             20000     0.49
      INSERTION             20000     0.38
          SHELL             20000     0.01
      SELECTION             40000     2.04
      INSERTION             40000     1.86
          SHELL             40000     0.01
      SELECTION             80000     8.53
      INSERTION             80000     8.37
          SHELL             80000     0.02
      SELECTION            160000    39.54
      INSERTION            160000    35.89
          SHELL            160000     0.06

POISSON DISTRIBUTION
      SELECTION             10000     0.28
      INSERTION             10000     0.16
          SHELL             10000     0.00
      SELECTION             20000     1.24
      INSERTION             20000     0.59
          SHELL             20000     0.00
      SELECTION             40000     4.67
      INSERTION             40000     2.44
          SHELL             40000     0.00
      SELECTION             80000    19.11
      INSERTION             80000     9.71
          SHELL             80000     0.01
      SELECTION            160000    67.54
      INSERTION            160000    39.29
          SHELL            160000     0.01

GEOMETRIC DISTRIBUTION
      SELECTION             10000     0.26
      INSERTION             10000     0.16
          SHELL             10000     0.00
      SELECTION             20000     1.06
      INSERTION             20000     0.63
          SHELL             20000     0.00
      SELECTION             40000     4.33
      INSERTION             40000     1.41
          SHELL             40000     0.00
      SELECTION             80000    15.51
      INSERTION             80000     5.32
          SHELL             80000     0.01
      SELECTION            160000    69.14
      INSERTION            160000    20.67
          SHELL            160000     0.02

DISCRETE DISTRIBUTION
      SELECTION             10000     0.09
      INSERTION             10000     0.06
          SHELL             10000     0.00
      SELECTION             20000     0.35
      INSERTION             20000     0.22
          SHELL             20000     0.00
      SELECTION             40000     1.37
      INSERTION             40000     0.88
          SHELL             40000     0.00
      SELECTION             80000     5.58
      INSERTION             80000     3.47
          SHELL             80000     0.00
      SELECTION            160000    22.31
      INSERTION            160000    14.13
          SHELL            160000     0.00


Question:
Consider the following implementation of the compareTo() method for String. How does the third line help with efficiency?
public int compareTo(String that)
{
 if (this == that) return 0; // this line
 int n = Math.min(this.length(), that.length());
 for (int i = 0; i < n; i++)
 {
 if (this.charAt(i) < that.charAt(i)) return -1;
 else if (this.charAt(i) > that.charAt(i)) return +1;
 }
 return this.length() - that.length();
}

Answer:
2.1.1
		a[]
i  min  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    1  E A S Y Q U E S T I  O  N
1    1  A E S Y Q U E S T I  O  N
2    6  A E S Y Q U E S T I  O  N
3    9  A E E Y Q U S S T I  O  N
4   11  A E E I Q U S S T Y  O  N
5   10  A E E I N U S S T Y  O  Q
6   11  A E E I N O S S T Y  U  Q
7    7  A E E I N O Q S T Y  U  S
8   11  A E E I N O Q S T Y  U  S
9   11  A E E I N O Q S S Y  U  T
10  10  A E E I N O Q S S T  U  Y
11  11  A E E I N O Q S S T  U  Y
	A E E I N O Q S S T  U  Y


Question: Write a program that reads a list of words from standard input and prints all two-word compound words in the list. For example, if after, thought, and afterthought are in the list, then afterthought is a compound word.

Answer:
2.1.2
The maximum number of exchanges involving any particular item during selection sort is N - 1.
This happens when the first item has the highest value in the unsorted array and the other values are sorted.
For example, in the array 4 1 2 3, the element 4 will be swapped N - 1 times.
The average number of exchanges involving an item is exactly 2, because there are exactly N exchanges and N items (and each exchange involves two items).

Reference: https://algs4.cs.princeton.edu/21elementary/


Question:
Criticize the following implementation of a class intended to represent account balances. Why is compareTo() a flawed implementation of the Comparable interface?
public class Balance implements Comparable<Balance>
{
 ...
 private double amount;
 public int compareTo(Balance that)
 {
 if (this.amount < that.amount - 0.005) return -1;
 if (this.amount > that.amount + 0.005) return +1;
 return 0;
 }
 ...
}
Describe a way to fix this problem.

Answer:
2.1.3
Array: H G F E D C B A

Thanks to QiotoF (https://github.com/QiotoF) for mentioning a better array solution for this exercise
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/76


Question: Implement a method String[] dedup(String[] a) that returns the objects in a[] in sorted order, with duplicates removed.

Answer:
2.1.4
		a[]
i    j  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    0  E A S Y Q U E S T I  O  N
1    0  A E S Y Q U E S T I  O  N
2    2  A E S Y Q U E S T I  O  N
3    3  A E S Y Q U E S T I  O  N
4    2  A E Q S Y U E S T I  O  N
5    4  A E Q S U Y E S T I  O  N
6    2  A E E Q S U Y S T I  O  N
7    5  A E E Q S S U Y T I  O  N
8    6  A E E Q S S T U Y I  O  N
9    3  A E E I Q S S T U Y  O  N
10   4  A E E I O Q S S T U  Y  N
11   4  A E E I N O Q S S T  U  Y
	A E E I N O Q S S T  U  Y


Question: Explain why selection sort is not stable.

Answer:
2.1.5

Condition 1: j > 0 -> When the array is reverse ordered
Z Q K D C B A

Condition 2: less(a[j], a[j - 1]) -> When the array is ordered
A B C D E F G


Question: Implement a recursive version of select().

Answer:
2.1.6

Insertion sort because it will only make one comparison with the previous element (per element) and won't exchange any elements,
running in linear time. Selection sort will exchange each element with itself and will run in quadratic time.

Thanks to glucu (https://github.com/glucu) for correcting the number of exchanges done in selection sort.


Question: About how many compares are required, on the average, to find the smallest of N items using select()?

Answer:
2.1.7

Selection sort because even though both selection sort and insertion sort will run in quadratic time, selection sort will
only make N exchanges, while insertion sort will make N * N / 2 exchanges.

Thanks to LudekCizinsky (https://github.com/LudekCizinsky), rg9a27 (https://github.com/rg9a27) and
BOTbkcd (https://github.com/BOTbkcd) for correcting the number of exchanges in selection sort.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/194 and
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/211


Question: Write a program Frequency that reads strings from standard input and prints the number of times each string occurs, in descending order of frequency.

Answer:
2.1.8

Quadratic. Insertion sort's running time is linear when the array is already sorted or all elements are equal.
With three possible values the running time quadratic.


Question: Develop a data type that allows you to write a client that can sort a file such as the one shown at right.

Answer:
2.1.9
				a[]
 h   i   j  0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
	    E A S Y S H E L L S  O  R  T  Q  U  E  S  T  I  O  N
13  13  13  E A S Y S H E L L S  O  R  T  Q  U  E  S  T  I  O  N
13  14  14  E A S Y S H E L L S  O  R  T  Q  U  E  S  T  I  O  N
13  15   2  E A E Y S H E L L S  O  R  T  Q  U  S  S  T  I  O  N
13  16   3  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  17  17  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  18  18  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  19  19  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
13  20  20  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
	    E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   4   4  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   5   5  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   6   6  E A E S S H E L L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   7   3  E A E L S H E S L S  O  R  T  Q  U  S  Y  T  I  O  N
 4   8   4  E A E L L H E S S S  O  R  T  Q  U  S  Y  T  I  O  N
 4   9   9  E A E L L H E S S S  O  R  T  Q  U  S  Y  T  I  O  N
 4  10  10  E A E L L H E S S S  O  R  T  Q  U  S  Y  T  I  O  N
 4  11   7  E A E L L H E R S S  O  S  T  Q  U  S  Y  T  I  O  N
 4  12  12  E A E L L H E R S S  O  S  T  Q  U  S  Y  T  I  O  N
 4  13   9  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  14  14  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  15  15  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  16  16  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  17  17  E A E L L H E R S Q  O  S  T  S  U  S  Y  T  I  O  N
 4  18  10  E A E L L H E R S Q  I  S  T  S  O  S  Y  T  U  O  N
 4  19   7  E A E L L H E O S Q  I  R  T  S  O  S  Y  T  U  S  N
 4  20   8  E A E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
	    E A E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   1   0  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   2   2  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   3   3  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   4   4  A E E L L H E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   5   3  A E E H L L E O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   6   3  A E E E H L L O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   7   7  A E E E H L L O N Q  I  R  S  S  O  S  T  T  U  S  Y
 1   8   7  A E E E H L L N O Q  I  R  S  S  O  S  T  T  U  S  Y
 1   9   9  A E E E H L L N O Q  I  R  S  S  O  S  T  T  U  S  Y
 1  10   5  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  11  11  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  12  12  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  13  13  A E E E H I L L N O  Q  R  S  S  O  S  T  T  U  S  Y
 1  14  10  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  15  15  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  16  16  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  17  17  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  18  18  A E E E H I L L N O  O  Q  R  S  S  S  T  T  U  S  Y
 1  19  16  A E E E H I L L N O  O  Q  R  S  S  S  S  T  T  U  Y
 1  20  20  A E E E H I L L N O  O  Q  R  S  S  S  S  T  T  U  Y
	    A E E E H I L L N O  O  Q  R  S  S  S  S  T  T  U  Y


Question: Create a data type Version that represents a software version number, such as 115.1.1, 115.10.1, 115.10.2. Implement the Comparable interface so that 115.1.1 is less than 115.10.1, and so forth.

Answer:
2.1.10
Insertion sort is faster than selection sort for h-sorting because as "h" decreases, the array becomes partially sorted.
Insertion sort makes less comparisons in partially sorted arrays than selection sort.
Also, when h-sorting, eventually h will have an increment value of 1.
Using selection sort with an increment value of 1 would be the same as using the standard selection sort algorithm from the beginning.
This would make the steps with the previous increments to be unnecessary work.

Thanks to jaeheonshim (https://github.com/jaeheonshim) for adding an extra reason not to use selection sort.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/254


Question: Load balancing. Write a program LPT.java that takes an integer M as a command-line argument, reads job names and processing times from standard input and prints a schedule assigning the jobs to M processors that approximately minimizes the time when the last job completes using the longest processing time first rule, as described on page 349.

Answer:
2.1.13 - Deck sort
I would use selection sort, comparing the cards first by suit, and if they have the same suit, by rank.
As we are dealing with physical objects it makes sense to minimize the number of swaps.
With selection sort it may be needed to look at more cards than insertion sort (twice as many in the average case),
but swaps will be required at most 52 times versus at most 676 times.

Thanks to zefrawg (https://github.com/zefrawg) and nedas-dev (https://github.com/nedas-dev) for improving this exercise:
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/198


Question: Sort by reverse domain. Write a data type Domain that represents domain names, including an appropriate compareTo() method where the natural order is in order of the reverse domain name. For example, the reverse domain of cs.princeton.edu is edu.princeton.cs. This is useful for web log analysis. Hint: Use s.split("\\.") to split the string s into tokens, delimited by dots. Write a client that reads domain names from standard input and prints the reverse domains in sorted order.

Answer:
2.1.14 - Dequeue sort
I would use a variation of bubble sort.

1- I would compare both top cards and, if the top card were bigger than the second card, I would swap them.
2- I would mark the top card, so I could know it was the first card (in this iteration) sent to the bottom of the deck.
3- I would send the top card to the bottom of the deck.
4- I would repeat steps 1 and 3 until the marked card becomes the second card in the deck
5- I would send the top card to the bottom of the deck (and the marked card is now at the top, signaling that a iteration is over)
6- If there were no swaps in this iteration, the deck is sorted. Otherwise, repeat steps 1 to 6.

Nice explanation here:
http://stackoverflow.com/questions/38061140/sort-a-deck-of-cards


Question: Spam campaign. To initiate an illegal spam campaign, you have a list of email addresses from various domains (the part of the email address that follows the @ symbol). To better forge the return addresses, you want to send the email from another user at the same domain. For example, you might want to forge an email from wayne@princeton.edu to rs@princeton.edu. How would you process the email list to make this an efficient task?

Answer:
2.1.15 - Expensive exchange

The clerk should use selection sort. Since the cost of compares is low, the N^2 complexity won't be a problem.
And it guarantees a cost of at most N exchanges.


Question: Idle time. Suppose that a parallel machine processes N jobs. Write a program that, given the list of job start and finish times, finds the largest interval where the machine is idle and the largest interval where the machine is not idle.

Answer:
2.1.20 - Shellsort best case

Just like insertion sort, the best case for shellsort is when the array is already ordered. This causes every element to
be compared only once in each iteration.
The time complexity in this case is O(n log n).

Good explanation: https://www.toptal.com/developers/sorting-algorithms/shell-sort
http://www.codingeek.com/algorithms/shell-sort-algorithm-explanation-implementation-and-complexity/


Question: Sampling for selection. Investigate the idea of using sampling to improve selection. Hint: Using the median may not always be helpful.

Answer:
2.1.23 - Deck sort

They separate all cards by suit, making the swaps in order to keep cards in the same suit next to each other (dividing the row in 4 areas).
Then, in each suit, they sort the cards by rank using selection sort.
In the second step (once suits are sorted), some of them move the unsorted smaller ranks near to the front while searching for the next smallest rank.


Question: Stable priority queue. Develop a stable priority-queue implementation (which returns duplicate keys in the same order in which they were inserted).

Answer:
2.1.24 - Insertion sort with sentinel

For 100000 random doubles
 Insertion Sort default is 1.1 times faster than Insertion Sort with a sentinel

Insertion Sort default is slightly faster than Insertion Sort with a sentinel.


Question: Points in the plane. Write three static comparators for the Point2D data type of page 77, one that compares points by their x coordinate, one that compares them by their y coordinate, and one that compares them by their distance from the origin. Write two non-static comparators for the Point2D data type, one that compares them by their distance to a specified point and one that compares them by their polar angle with respect to a specified point.

Answer:
2.1.25 - Insertion sort without exchanges

For 100000 random doubles
 Insertion Sort default is 0.7 times faster than Insertion Sort without exchanges

Insertion Sort without exchanges is faster than Insertion Sort default.


Question: Simple polygon. Given N points in the plane, draw a simple polygon with N points as vertices. Hint: Find the point p with the smallest y coordinate, breaking ties with the smallest x coordinate. Connect the points in increasing order of the polar angle they make with p.

Answer:
2.1.26 - Primitive types

For 100000 random doubles
 Insertion Sort with primitives is 2.0 times faster than Insertion Sort with objects

Insertion Sort with primitives is faster than Insertion Sor with objects.


Question: Sorting parallel arrays. When sorting parallel arrays, it is useful to have a version of a sorting routine that returns a permutation, say index[], of the indices in sorted order. Add a method indirectSort() to Insertion that takes an array of Comparable objects a[] as argument, but instead of rearranging the entries of a[] returns an integer array index[] so that a[index[0]] through a[index[N-1]] are the items in ascending order.

Answer:
2.1.27 - Shellsort is subquadratic

For a total of 11 experiments with 128, 256, ..., 262,144 values

Shell Sort is 343.0 times faster than Selection Sort
Shell Sort is 338.8 times faster than Insertion Sort


Question: Sort files by name. Write a program FileSorter that takes the name of a directory as a command-line argument and prints out all of the files in the current directory, sorted by file name. Hint: Use the File data type.

Answer:
2.1.28 - Equal keys

From the book we know that:
Proposition A. Selection sort uses ~(N^2 / 2) compares and N exchanges to sort an array of length N.
Proposition B. Insertion sort uses ~(N^2 / 4) compares and ~(N^2 / 4) exchanges to sort a randomly ordered array of
length N with distinct keys, on the average. The worst case is ~(N^2 / 2) compares and ~(N^2 / 2) exchanges and the best
case is N - 1 compares and 0 exchanges.

Thus the running time of selection sort is bound by O(N^2 / 2) and insertion sort averages on O(N^2 / 2)
(this is because ~(N^2 / 4) compares + ~(N^2 / 4) exchanges = ~(N^2 / 4)).

For arrays with 2 key values (assuming value 1 and value 2) of equal probability:
* Selection sort: it still needs to scan N - K elements to sort the Kth element.
  So its asymptotic running time remains the same O(N^2 / 2).
* Insertion sort: when sorting the (K + 1)th element, there are already K / 2 ones and K / 2 twos sorted.
  Thus the (random variable) expected value of the running time for sorting the (K + 1)th element is:
  0.5 * 1 + 0.5 * K
  Thus the total running time for K = 0, 1, 2, ..., N is:
  0.5 * N + ((N + 1) * N / 2) * 0.5 = 3N/4 + (N ^ 2) / 4 ~= O(N^2 / 4)
  Comparing O(N^2 / 4) against O(N^2 / 2) we can make the hypothesis that the running time of insertion sort with
  2 key values is half of that for random values.

Hypothesis:
1- Selection sort will take the same time for both arrays with different values and arrays with only 2 possible values.
2- Insertion sort will take half the same for arrays with only 2 possible values than for arrays with different values.

Validation:

Selection Sort
For an array of size 128:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 256:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 512:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 1024:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 2048:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 4096:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 8192:
Time for an array with any values: 0.1
Time for an array with 2 values: 0.1

For an array of size 16384:
Time for an array with any values: 0.2
Time for an array with 2 values: 0.2

For an array of size 32768:
Time for an array with any values: 1.0
Time for an array with 2 values: 0.7

For an array of size 65536:
Time for an array with any values: 4.4
Time for an array with 2 values: 3.0

For an array of size 131072:
Time for an array with any values: 20.9
Time for an array with 2 values: 11.7

Insertion Sort
For an array of size 128:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 256:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 512:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 1024:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 2048:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 4096:
Time for an array with any values: 0.0
Time for an array with 2 values: 0.0

For an array of size 8192:
Time for an array with any values: 0.1
Time for an array with 2 values: 0.0

For an array of size 16384:
Time for an array with any values: 0.2
Time for an array with 2 values: 0.1

For an array of size 32768:
Time for an array with any values: 1.0
Time for an array with 2 values: 0.4

For an array of size 65536:
Time for an array with any values: 4.3
Time for an array with 2 values: 1.5

For an array of size 131072:
Time for an array with any values: 18.9
Time for an array with 2 values: 6.3

--------
Result:
1- Selection sort is faster for arrays with only 2 possible values than for arrays with different values.
2- Insertion sort is a lot faster (about a third of the time) for arrays with only 2 possible values than for arrays with different values.

Also, insertion sort is faster than selection sort for sorting arrays with only 2 possible values.

Thanks to faame (https://github.com/faame) for improving the analysis.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/216


Question: Sort files by size and date of last modification. Write comparators for the type File to order by increasing/decreasing order of file size, ascending/descending order of file name, and ascending/descending order of last modification date. Use these comparators in a program LS that takes a command-line argument and lists the files in the current directory according to a specified order, e.g., "-t" to sort by timestamp. Support multiple flags to break ties. Be sure to use a stable sort.

Answer:
2.1.29 - Shellsort increments

Sedgewicks's sequence is faster than the 3N + 1 sequence.

Experiments:

For an array of size 32768:
3N + 1 sequence: 0.0
Sedgewicks's sequence: 0.0

For an array of size 65536:
3N + 1 sequence: 0.0
Sedgewicks's sequence: 0.0

For an array of size 131072:
3N + 1 sequence: 0.1
Sedgewicks's sequence: 0.0

For an array of size 262144:
3N + 1 sequence: 0.1
Sedgewicks's sequence: 0.1

For an array of size 524288:
3N + 1 sequence: 0.3
Sedgewicks's sequence: 0.3

For an array of size 1048576:
3N + 1 sequence: 1.0
Sedgewicks's sequence: 0.7

For an array of size 2097152:
3N + 1 sequence: 2.5
Sedgewicks's sequence: 1.8

For an array of size 4194304:
3N + 1 sequence: 7.2
Sedgewicks's sequence: 4.5

For an array of size 8388608:
3N + 1 sequence: 18.4
Sedgewicks's sequence: 11.2

For an array of size 16777216:
3N + 1 sequence: 46.0
Sedgewicks's sequence: 26.6


Question: Boerner’s theorem. True or false: If you sort each column of a matrix, then sort each row, the columns are still sorted. Justify your answer.

Answer:
2.1.30 - Geometric increments

Best 1 tValue: 2.10
Best 1 sequence:
1 2 4 9 19 40 85 180 378 794 1667 3502 7355 15447 32439 68122 143056 300419 630880

Best 2 tValue: 2.40
Best 2 sequence:
1 2 5 13 33 79 191 458 1100 2641 6340 15216 36520 87648 210357 504857

Best 3 tValue: 2.20
Best 3 sequence:
1 2 4 10 23 51 113 249 548 1207 2655 5843 12855 28281 62218 136880 301136 662499


Question: Give the number of calls to put() and get() issued by FrequencyCounter, as a function of the number W of words and the number D of distinct words in the input.

Answer:
3.1.6

The put() method will be called once for every word.
The get() method will be called once for every word, except on the first time a word in being inserted in the symbol table.

Calls to put() = W
Calls to get() = W - D

Thanks to faame (https://github.com/faame) for suggesting a better answer.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/221


Question: What is the average number of distinct keys that FrequencyCounter will find among N random nonnegative integers less than 1,000, for N=10, 10^2, 10^3, 10^4, 10^5, and 10^6?

Answer:
3.1.7

Number of distinct keys among 10 random nonnegative integers less than 1000: 10
Number of distinct keys among 100 random nonnegative integers less than 1000: 97
Number of distinct keys among 1000 random nonnegative integers less than 1000: 635
Number of distinct keys among 10000 random nonnegative integers less than 1000: 999
Number of distinct keys among 100000 random nonnegative integers less than 1000: 1000
Number of distinct keys among 1000000 random nonnegative integers less than 1000: 1000


Question: What is the most frequently used word of ten letters or more in Tale of Two Cities?

Answer:
3.1.8

Most frequently used word of ten letters or more in Tale of Two Cities: Monseigneur Frequency: 47


Question: Add code to FrequencyCounter to keep track of the last call to put(). Print the last word inserted and the number of words that were processed in the input stream prior to this insertion. Run your program for tale.txt with length cutoffs 1, 8, and 10.

Answer:
3.1.9

Length cutoff Last word inserted  Words processed
            1            known."           135937
            8          faltering           135905
           10      disfigurement           135890


Question: Give a trace of the process of inserting the keys E A S Y Q U E S T I O N into an initially empty table using SequentialSearchST. How many compares are involved?

Answer:
3.1.10

key  value  first
 E     0      E0                                         0 compares
 A     1      A1  E0                                     1 compare
 S     2      S2  A1  E0                                 2 compares
 Y     3      Y3  S2  A1  E0                             3 compares
 Q     4      Q4  Y3  S2  A1  E0                         4 compares
 U     5      U5  Q4  Y3  S2  A1  E0                     5 compares
 E     6      U5  Q4  Y3  S2  A1  E6                     6 compares
 S     7      U5  Q4  Y3  S7  A1  E6                     4 compares
 T     8      T8  U5  Q4  Y3  S7  A1  E6                 6 compares
 I     9      I9  T8  U5  Q4  Y3  S7  A1  E6             7 compares
 O    10      O10  I9  T8  U5  Q4  Y3  S7  A1  E6        8 compares
 N    11      N11  O10  I9  T8  U5  Q4  Y3  S7  A1  E6   9 compares

Total: 55 compares

Thanks to ebber22 (https://github.com/ebber22) for finding an issue with the way the nodes were being added.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/102


Question: Give a trace of the process of inserting the keys E A S Y Q U E S T I O N into an initially empty table using BinarySearchST. How many compares are involved?

Answer:
3.1.11

			keys[]				            vals[]
key  value    0  1  2  3  4  5  6  7  8  9    N   0  1  2  3  4  5  6  7  8  9
 E     0      E                               1   0                               0 compares
 A     1      A  E                            2   1  0                            2 compares
 S     2      A  E  S                         3   1  0  2                         2 compares
 Y     3      A  E  S  Y                      4   1  0  2  3                      2 compares
 Q     4      A  E  Q  S  Y                   5   1  0  4  2  3                   3 compares
 U     5      A  E  Q  S  U  Y                6   1  0  4  2  5  3                4 compares
 E     6      A  E  Q  S  U  Y                6   1  6  4  2  5  3                4 compares
 S     7      A  E  Q  S  U  Y                6   1  6  4  7  5  3                4 compares
 T     8      A  E  Q  S  T  U  Y             6   1  6  4  7  8  5  3             4 compares
 I     9      A  E  I  Q  S  T  U  Y          6   1  6  9  4  7  8  5  3          4 compares
 O    10      A  E  I  O  Q  S  T  U  Y       6   1  6  9  10 4  7  8  5  3       4 compares
 N    11      A  E  I  N  O  Q  S  T  U  Y    6   1  6  9  11 10 4  7  8  5  3    5 compares
              A  E  I  N  O  Q  S  T  U  Y        1  6  9  11 10 4  7  8  5  3

Total: 38 compares


Question: Which of the symbol-table implementations in this section would you use for an application that does 10^3 put() operations and 10^6 get() operations, randomly intermixed? Justify your answer.

Answer:
3.1.13

For an application that does 10^3 put() operations and 10^6 get() operations I would use a binary search symbol table implementation.
The application does a lot more get() than put() operations and a binary search symbol table implementation has a O(log(n)) runtime complexity for the get() operation, which is better than the O(n) runtime complexity of the sequential search symbol table implementation.


Question: Which of the symbol-table implementations in this section would you use for an application that does 10^6 put() operations and 10^3 get() operations, randomly intermixed? Justify your answer.

Answer:
3.1.14

For an application that does 10^6 put() operations and 10^3 get() operations I would use a sequential search symbol table implementation.

The worst-case runtime cost of the put() operation for a binary search symbol table is 2N while for a sequential search symbol table it is N.
For the get() operation, the worst-case runtime cost of a binary search symbol table is lg(n) while for the sequential search symbol table it is N.

Comparing the total number of operations in the worst-case:
Sequential search symbol table: 10^6 + 10^3 ~ 10^6 operations
Binary search symbol table: 2 * 10^6 + lg(10^3) ~ 2 * 10^6 operations

The average-case runtime cost of both implementations in this case is similar because most of the operations are put() and both the sequential search symbol table and the binary search symbol table implementations have an average-case cost of N for it.

So for this application the sequential search symbol table performs better than the binary search symbol table in the worst-case and both perform similarly in the average-case, making the sequential search symbol table the best choice.

Thanks to dragon-dreamer (https://github.com/dragon-dreamer) for showing that the sequential search symbol table is the best option in this question.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/119


Question: Assume that searches are 1,000 times more frequent than insertions for a BinarySearchST client. Estimate the percentage of the total time that is devoted to insertions, when the number of searches is 10^3, 10^6, and 10^9.

Answer:
3.1.15

     Searches Percentage of total time spent on insertions
         1000                                        0.00%
      1000000                                        6.10%
   1000000000                                       96.26%

The average insertion cost is N, so the total insertion cost for N keys is N^2.
The average search cost is lg N, so the total search cost for M keys is M * lg N.
According to the question, M = 1000 * N.

The total cost is then:
total cost = N^2 + M * lg N = N^2 + 1000N * lg N

The insertion percentage is:
P = (N^2) / (N^2 + 1000N * lg N)
N^2 is the higher-order element in the equation, so as N increases, the insertion percentage approaches 100%.

Thanks to faame (https://github.com/faame) for improving this answer.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/222


Question: Prove that the rank() method in BinarySearchST is correct.

Answer:
3.1.18

The rank() method in BinarySearchST always starts the search in the middle of the array if it has an odd number of elements.
If the array has an even number of elements, the rank() method starts the search on the left of the two middle elements.
After comparing the middle element with the search key, if it is smaller, the search continues on the right side of the array.
If it is bigger, the search continues on the left side of the array.
If they have the same value, the current element's index is the rank we are looking for.

This guarantees that if an element exists in the symbol table its rank will be found in the rank() method.

When the element does not exist the value of the "low" variable will have passed the value of the "high" variable, pointing to the correct rank of where the key should be. This only happens when both the element on the left of the final rank has been checked and the element on the current (final) rank has been checked. After these checks, low will be pointing to the correct rank location.

Example:

Symbol Table: 0 1 2 3 5 6
Rank of key 4 (non-existent)

1- The initial search range is [0..5]. The rank() method checks the left of the middle elements on index 2 -> value 2
2- 2 is less than 4, so the new range to search is [3..5]. The rank() method checks the middle element on index 4 -> value 5
3- 5 is more than 4, so the new range to search is [3..3]. The rank() method checks the only element left (index 3) -> value 3
4- 3 is less than 4, so the new range to search is [4..3]. Now the "low" variable is bigger than the "high" variable.
5- The rank() method returns the value of the "low" variable, 4. This is the correct rank for key 4.


Question: Complete the proof of Proposition B (show that it holds for all values of N). Hint: Start by showing that C(N) is monotonic: C(N) <= C(N+1) for all N > 0.

Answer:
3.1.20

Proposition B. Binary search in an ordered array with N keys uses no more than lg N + 1 compares for a search (successful or unsuccessful).

Proof: Let C(N) be the number of compares to search for a key in a symbol table of size N.
We have C(0) = 0, C(1) = 1, and for N > 0 we can write a recurrence relationship that directly mirrors the recursive method:
C(N) <= C(FLOOR(N / 2)) + 1

Whether the search goes to the left or to the right, the size of the subarray is no more than FLOOR(N / 2), and we can use one compare to check for equality and to choose whether to go left or right.

Let's first prove by induction that C(N) is monotonic: C(N) <= C(N + 1) for all N > 0.

It is trivial to prove that:
C(1) = 1
C(2) = 1 or 2

Thus we have:
C(1) <= C(2)

Assume for all N=[0, K]
C(N + 1) >= C(N)

Thus we have:
C(K + 1) >= C(K)

At the beginning of the binary search, low has value 0 and high has value N. Mid is computed as:
mid = low + (high - low) / 2 = high / 2

Let's use L to represent the size of the left half and R to represent the size of the right half.
The mid element has size 1.
When N = K + 1 the total size is L + 1 + R.

When N = K + 2:
mid = low + (high - low) / 2 = (high + 1) / 2 = (N + 1) / 2

When N is incremented by 1 (from K + 1 to K + 2), the mid point either remains in the same place or shifts to the right by 1.
1- If mid remains in the same place, then L remains the same, and R is incremented by 1.
Since (R + 1) <= K + 1, we have:
C(K + 2) = C(L) + 1 + C(R + 1) >= C(L) + 1 + C(R) = C(K + 1)
2- If mid shifts to the right by 1, then L is incremented by 1 and R remains the same.
Since (L + 1) <= K + 1, we have:
C(K + 2) = C(L + 1) + 1 + C(R) >= C(L) + 1 + C(R) = C(K + 1)

Therefore, given C(K + 1) >= C(K) it is also true that C(K + 2) >= C(K + 1), which proves that C(N) is monotonic.

For a general N, we have that:

C(N) <= C(N / 2) + 1 (one comparison to check equality or decide which way of the subarray to go)
C(N / 2) <= C(N / 4) + 1

Putting the value of C(N / 2) in the first equation:
C(N) <= C(N / 4) + 1 + 1

And adding all values to the first equation until C = 1:
C(N) <= C(N / 8) + 1 + 1 + 1
C(N) <= C(N / 16) + 1 + 1 + 1 + 1
C(N) <= C(N / 2^k) + 1 + 1 + 1 + 1 + ... + 1

until we get to
C(N) <= 1 + 1 + 1 + 1 + 1 + ... + 1 (even if N is not divisible by 2 there is still a compare operation)
C(N) <= k + 1

In this case, 2^k = N
k <= lg N + 1

We can also prove it using the Master theorem:

Binary search recurrence relation:
T(N) = T(N/2) + O(1)

Master theorem:
T(N) = aT(N/b) + f(N)

Here, a = 1, b = 2 and f(n) is O(1) (constant)

c = log(a base b) = log(1 base 2) = 0

We can see that this is the case 2 of the Master theorem by taking k = 0 in this equation:
O(n^c * (log n)^k)
O(n^0 * (log n)^0) = O(1) = f(n) -> This means we are in case 2 of the Master theorem

From the Case 2 of the Master Theorem we know that:
T(n) = O(n^(log a base b) * (log n)^(k + 1))
T(n) = O(n^0 * log(n)^1) = O(log n)

With binary search, we achieve a logarithmic-time search guarantee.

Reference: https://en.wikipedia.org/wiki/Master_theorem

Thanks to faame (https://github.com/faame) for adding the section proving that C(N) is monotonic.
https://github.com/reneargento/algorithms-sedgewick-wayne/issues/223