Part A · In-place Merge Sort
5 marks
Write an in-place Merge Sort algorithm. Discuss the time complexity of the algorithm.
Algorithm: IN-PLACE-MERGE-SORT(A, left, right)
1. If left ≥ right, return.
2. Set mid ← ⌊(left + right) / 2⌋.
3. Call IN-PLACE-MERGE-SORT(A, left, mid).
4. Call IN-PLACE-MERGE-SORT(A, mid + 1, right).
5. Call GAP-MERGE(A, left, right).
Initially, call IN-PLACE-MERGE-SORT(A, 0, n − 1). In step 5, both adjacent halves are already sorted.
Algorithm: GAP-MERGE(A, left, right)
1. Set length ← right − left + 1.
2. If length ≤ 1, return.
3. Set gap ← ⌈length / 2⌉.
4. While gap > 0, repeat:
a. Set i ← left and j ← left + gap.
b. While j ≤ right, repeat:
i. If A[i] > A[j], swap A[i] and A[j].
ii. Set i ← i + 1 and j ← j + 1.
c. If gap = 1, set gap ← 0.
Otherwise, set gap ← ⌈gap / 2⌉.
5. Return.
For nine elements, the gaps are 5, 3, 2 and 1.
Time complexity
A merge of m elements has O(log m) gap passes, each taking O(m) time. Hence one gap-merge takes O(m log m). Using this merge at every level of Merge Sort gives:
T(n) = 2T(n/2) + O(n log n)
T(n) = O(n log² n)
Full sort: O(n log² n). The merge uses O(1) extra space. The recursive sort additionally uses O(log n) stack space.
Alternative: swap and re-sort
- For two sorted arrays A and B of sizes n and m, set i ← n − 1 and j ← 0.
- While i ≥ 0 and j < m, compare A[i] and B[j]. If A[i] > B[j], swap them, decrease i by 1 and increase j by 1. Otherwise, stop the scan.
- Sort A and B separately in place. Their concatenation is now sorted.
Time complexity: O(min(n, m)) + O(n log n) + O(m log m).
Part B · Why two-way partitioning?
2 marks
Why do Merge Sort and Quick Sort generally use two-way partitioning instead of more than two parts? Does a smaller recursion depth, such as log₃ n instead of log₂ n, necessarily reduce the overall time complexity?
No. Changing the depth from log₂ n to log₃ n gives only a constant-factor improvement, since
log₃ n = log₂ n / log₂ 3.
Therefore, n log₂ n and n log₃ n are both Θ(n log n). Dividing into three parts does not improve the asymptotic time complexity. Two-way splitting is simpler; fewer recursion levels alone do not change the order of growth.
Part C · Sort 90 GB using a min-heap
5 marks
Suppose you have 90 GB of unsorted data stored on a hard disk, while the available RAM is only 10 GB. Write an algorithm to efficiently sort the entire dataset using a min-heap data structure.
Algorithm: EXTERNAL-SORT
- Divide the 90 GB dataset into chunks that fit in the 10 GB RAM. Ignoring working-space overhead, this gives nine chunks of 10 GB each; leave room for working memory in an implementation.
- Read one chunk into RAM, sort it, and write the sorted chunk back to disk as a separate file.
- Repeat step 2 for every chunk.
- Read about 90 MB of complete records from each sorted file into a separate input buffer in RAM. Also reserve an output buffer of about 90 MB.
- Create a min-heap.
- Extract the minimum element from the heap and append it to the output buffer.
- Advance to the next element in the input buffer that supplied the extracted element. If that buffer is exhausted, refill it with the next block of about 90 MB from the same file. Insert the next element into the min-heap. If both the buffer and its file are exhausted, do not insert a replacement.
- When the output buffer reaches about 90 MB, append its contents to the output file on disk and empty the buffer.
- Repeat steps 6–8 until the heap becomes empty.
- Write any remaining elements in the output buffer to disk. The output file now contains all 90 GB in sorted order.
Each input buffer contributes only its smallest unprocessed element to the heap. The remaining elements stay in the buffer. This keeps the output globally sorted while disk reads and writes take place in blocks.
For nine sorted files, the input buffers use about 9 × 90 MB = 810 MB. Including the 90 MB output buffer gives about 900 MB, plus the small heap and bookkeeping, which fits within 10 GB RAM.
Merge time: O(N log k), where N is the total number of elements and k is the number of sorted files. For nine files, this is O(N log 9). The heap holds at most k elements.