3.3. Divide & Conquer Sort
Merge sort, quick sort, intro sort
Divide & Conquer
Divide the problem into sub-problems (recursively).
Conquer sub-problems, which effectively solve the super problem.
Why do people ever want to use QuickSort?
Divide the input array into two sub-arrays.
Sort each of the sub-arrays and merge them into the back.
Let us create the class inheriting AbstractSort:
L2: holds the copy of the input array.
Let us then override the sort() method that calls the helper method:
L4-5: increases the size of the temp array if necessary.
L5: unchecked type Object to T[].
What is the advantage of declaring the member field temp?
The helper method can be defined as follows:
L11: sorts the left sub-array.
L12: sorts the right sub-array.
L13: merges the left and right sub-arrays.
Finally, the merge() method can be defined as follows:
L10-11: copies the input array to the temporary array and counts the assignments.
L14-15: no key left in the 1st half.
How many assignments are made for the number of keys by the above version of MergeSort?
Pick a pivot key in the input array.
Exchange keys between the left and right partitions such that all keys in the left and right partitions are smaller or bigger than the pivot key, respectively.
Repeat this procedure in each partition, recursively.
Let us create the class inheriting AbstractSort:
Let us then override the sort() method:
L3: stops when the pointers are crossed.
L6: sorts the left partition.
L7: sorts the right partition.
The partition() method can be defined as follows:
L5: finds the left pointer where endIndex > fst > pivot.
L6: finds the right pointer where beginIndex < snd
Although Quick Sort is the fastest on average, the worst-case complexity is .
sorting algorithms that guarantee faster worst-case complexities than Quick Sort:
Quick Sort for random cases and a different algorithm for the worst case.
How can we determine if Quick Sort is meeting the worse-case?
Let us define the IntroSoft class inheriting QuickSort:
L2: declares a sorting algorithm to handle the worst cases.
L14: resets the counters for both the main and auxiliary sorting algorithms.
We then override the sort() method by passing the maximum depth to the auxiliary method:
L9: returns as the maximum depth.
Finally, the auxiliary method sort() can be defined as follows:
L4-5: switches to the other sorting algorithm if the depth of the partitioning exceeds the max depth.
Does the max-depth need to be set to ?
The following shows runtime speeds, assignment costs, and comparison costs between several sorting algorithms for the random, best, and worst cases.