Java - Sorting Algorithms
How many passes does it take to sort an array of n elements (w/ selection/insertion sort)?
n-1 passes
Selection Sort
"search-and-swap" algorithm
How does selection sort work?
1. Finds the smallest element in the list/array and swaps it with the first element (a[0]) 2. Finds the second smallest element, in range a[1]...a[n-1], and swaps it with the second element (a[1]) 3. Continues to do this until we reach the last two elements, a[n-2] and a[n-1] 4. The smaller of the last two elements is placed in a[n-2], the larger in a[n-1], and the sort is complete
How does quicksort work?
1. Split the array into two sub-arrays by using the partition method: randomly pick a pivot element (often just the first element) 2. Compare all the rest of the elements to the pivot 3. If they are greater than/equal to the pivot, put them to the right 4. If they are less than/equal to the pivot, put them to the left 5. Put a "down" counter at the first element (a[0]), "up" counter at the last (a[n-1]) 6. Advance "down" forward until a value higher than pivot is found, or "down" = "up" 7. Advance the "up" backwards until a value lower than pivot is found, or "up" = "down" 8. Swap the two elements, a[down] and a[up] 9. Continue the swapping process until "down" = "up" 10. Where "up" and "down" meet is the pivot position; swap a[0] and a[pivotPosition]
How does mergesort work?
1. Start with an unsorted list of n elements. 2. Recursive calls break the original list into n sub-lists, each w/ length 1. (Note that these n arrays, each containing just one element, are sorted! ) 3. Recursively merge adjacent pairs of lists. When the adjacent pairs are merged, they also get sorted in ascending order. 4. There will then be approximately n/2 lists of length 2; then, approximately n/4 lists of approximate length 4, and so on, until only one list of length n remains
How does insertion sort work?
1. Starting with the second element (a[1]), you go one-by-one throughout the elements in the array and "insert them" (by swapping) accordingly into the sorted array on the left (in the correct order) 2. When you reach the end of the array , the last element would be pushed to the end of the array and be where it should be, w/ the rest of the list also sorted correctly
How the sorting would look like after each pass (in both selection/insertion sort)
8 1 4 6 1 8 4 6 After first pass 1 4 8 6 After second pass 1 4 6 8 After third pass
What approach is more efficient when dealing with large n?
A "divide-and-conquer" approach (used in both mergesort and quicksort)
How does quicksort work? (recursive description)
If there are at least two elements in the array... Partition the array. Quicksort the left subarray. Quicksort the right subarray.
How does mergesort work? (recursive description)
If there is more than one element in the array.... Break the array into two halves. Mergesort the left half. Mergesort the right half. Merge the two subarrays into a sorted array.
What makes mergesort so efficient in comparision to insertion or selection sort?
It is not affected by the initial ordering of the elements, meaning that best, worst, and average cases have similar run times
What is the main disadvantage of mergesort?
It uses a temporary array that has to be as large as the original, unsorted array (may become a problem if space is a factor)
What is the main disadvantage of quicksort?
Its worst case behavior is very inefficient
Is the number of passes proportional to the number of elements in their final positions (w/ insertion sort)?
No, after the kth pass (a[0], a[1], . . . , a[k]) are sorted with respect to each other, but are not necessarily in their final sorted positions
What should you do for the fastest run time?
Partition the array into two parts of roughly the same size
Insertion Sort
The first element in the array (a[0]) is sorted with respect to itself. The array can then be thought of as two parts, a sorted list followed by an unsorted list.
What happens is the pivot happens to be the smallest/largest element in the array?
The split is not much of a split b/c one of the sub-arrays end up empty! If this happens repeatedly, quicksort degenerates into a slow, recursive version of selection sort and becomes very inefficient.
Why are insertion and selection sort inefficient for large n?
They require approximately n passes to sort through a list of n elements
When does it become faster to sort by insertion instead of mergesort/quicksort?
When a subarray gets down to some small size m, it becomes faster to sort by straight insertion. The optimal value of m is machine-dependent, but it's approximately equal to 7.
What is the best case for insertion sort?
When the array is already sorted in increasing order. In this case, each pass through the array will only involve a single comparison, indicating that "it" is in its correct position with respect to the sorted list. Therefore, no elements will need to be moved.
What is the worst case for insertion sort?
When the array is initially sorted in reverse order, since this will lead to the maximum possible number of comparisons/moves
What is the worst case for quicksort?
When the partitioning algorithm repeatedly divides the array into pieces of size 1 and n − 1. Some algorithms avoid this situation by initially shuffling up the given array or selecting the pivot by examining several elements of the array (ex. first, middle, and last) and then taking the median.
Is the number of passes proportional to the number of elements in their final positions (w/ selection sort)?
Yes, after the kth pass, the first k elements would be in their final sorted positions
What are the two types of recursive sorts?
mergesort and quicksort
For large n, what is the fastest known sorting algorithm?
quicksort (as per it's name :>)
What does a sorting algorithm do?
sorts an array of n elements (a[0], a[1], . . . , a[n-1]) in ascending order