Recursive Searching and Sorting
Skill 4.ASkill 4.B
Big idea: Binary search and merge sort both split the data in half. Binary search throws half away each step; merge sort sorts both halves and merges them.
- Determine the result of executing recursive algorithms that use strings or collections.
- Determine the result of each iteration of a binary search algorithm used to search for information in a collection.
- Determine the result of each iteration of the merge sort algorithm when used to sort a collection.
Binary search
Binary search only works on sorted data. Check the middle element; if it isn't the target, keep only the half that could contain it.
Methodsstatic int search(int[] a, int target) {
int lo = 0, hi = a.length - 1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
System.out.println("check index " + mid + " (" + a[mid] + ")");
if (a[mid] == target) return mid;
if (a[mid] < target) lo = mid + 1;
else hi = mid - 1;
}
return -1;
}Using themint[] a = {2, 5, 8, 12, 16, 23, 38, 56, 72, 91};
System.out.println(search(a, 23));Outputcheck index 4 (16) check index 7 (56) check index 5 (23) 5
How fast is it?
Each check halves what's left, so n items take about log₂(n) checks. 1,000 items take about 10; 1,000,000 take about 20. Linear search on the same data could take 1,000,000.
Merge sort
Split the list in half, recursively sort each half, then merge the two sorted halves by repeatedly taking the smaller front element.
Methodsstatic void mergeSort(int[] a, int lo, int hi) {
if (lo >= hi) return;
int mid = (lo + hi) / 2;
mergeSort(a, lo, mid);
mergeSort(a, mid + 1, hi);
int[] temp = new int[hi - lo + 1];
int i = lo, j = mid + 1, k = 0;
while (i <= mid || j <= hi) {
if (j > hi || (i <= mid && a[i] <= a[j])) {
temp[k] = a[i];
i++;
} else {
temp[k] = a[j];
j++;
}
k++;
}
for (k = 0; k < temp.length; k++) a[lo + k] = temp[k];
}Using themint[] a = {38, 27, 43, 3, 9, 82, 10};
mergeSort(a, 0, a.length - 1);
System.out.println(Arrays.toString(a));Output[3, 9, 10, 27, 38, 43, 82]Merge sort, step by step
| Step | State |
|---|---|
| Split | [38, 27, 43, 3] [9, 82, 10] |
| Split again | [38, 27] [43, 3] [9, 82] [10] |
| Down to singles | [38] [27] [43] [3] [9] [82] [10] |
| Merge pairs | [27, 38] [3, 43] [9, 82] [10] |
| Merge | [3, 27, 38, 43] [9, 10, 82] |
| Final merge | [3, 9, 10, 27, 38, 43, 82] |
- Recursion can traverse Strings, arrays, and ArrayLists.
- Binary search needs sorted data, checks the middle, and discards half each step.
- Binary search is usually much faster than linear search.
- Merge sort: split in half, sort each half recursively, merge the sorted halves.
- Binary search on unsorted data gives wrong answers.
- With integer division,
mid = (lo + hi) / 2rounds down.
- For "which elements are checked" questions, keep lo, hi, and mid in a little table.
Binary search for 8 in {1, 3, 5, 7, 8, 10, 12}: which values are checked?
Show answer
7 (index 3), then 10 (index 5), then 8 (index 4).
- Search algorithms other than linear and binary.
- Sorts other than selection, insertion, and merge sort.