3.1.4 - Merge sort and sort comparisons
Merge sort divides a list into smaller lists, then builds the sorted result by merging ordered lists. Understanding the merge step explains how the method creates order without bubble sort's repeated adjacent swaps.
Splitting into smaller lists
Merge sort repeatedly splits a list into smaller lists until each contains a single item, then merges those lists back together in order.
Merge sort
A sorting algorithm that divides a list into smaller lists and combines ordered lists through repeated merging to produce a sorted result.
Start with [8, 3, 6, 1, 7, 2, 5, 4]. Split it into [8, 3, 6, 1] and [7, 2, 5, 4]. Split each half into two pairs, then split the pairs into single items. Splitting follows positions in the list; it does not move small values to one half and large values to the other.

The split stages preserve the original values and order within each smaller list. The merge stages then produce ordered pairs, ordered four-item lists and finally the complete ordered list.
A single-item list is already sorted because there is no pair of items in the wrong order. These lists provide the starting point for merging. Splitting alone has not sorted the original collection: its single items still appear in the original sequence 8, 3, 6, 1, 7, 2, 5, 4 across the diagram.
Merging 8 with 3 produces [3, 8]; merging 6 with 1 produces [1, 6]. The other pairs become [2, 7] and [4, 5]. Merging the first two ordered pairs gives [1, 3, 6, 8]; merging the other two gives [2, 4, 5, 7]. The final merge produces [1, 2, 3, 4, 5, 6, 7, 8].
If a list has an odd number of items, one split portion can have one more item than the other. The method still works: its merge step can combine ordered lists of different lengths. An empty or single-item list already needs no sorting.
Merging ordered lists
To merge two ordered lists, repeatedly compare their first unconsumed items, take the smaller item and advance only in the list from which it was taken.
For the final merge in the diagram, the left list is [1, 3, 6, 8] and the right list is [2, 4, 5, 7]. Track the next unused position in each list:
| Comparison | Left front | Right front | Item taken | Result so far |
|---|---|---|---|---|
| 1 | 1 | 2 | 1 from left | [1] |
| 2 | 3 | 2 | 2 from right | [1, 2] |
| 3 | 3 | 4 | 3 from left | [1, 2, 3] |
| 4 | 6 | 4 | 4 from right | [1, 2, 3, 4] |
| 5 | 6 | 5 | 5 from right | [1, 2, 3, 4, 5] |
| 6 | 6 | 7 | 6 from left | [1, 2, 3, 4, 5, 6] |
| 7 | 8 | 7 | 7 from right | [1, 2, 3, 4, 5, 6, 7] |
The right list is now exhausted. Append the remaining 8 from the left list without another comparison between fronts. The final result is [1, 2, 3, 4, 5, 6, 7, 8], using seven front-item comparisons for this merge.
Taking the smaller front item is justified because each source list is already ordered: no later item in either list can be smaller than its own front item. After taking an item, leave the other list's front where it is. Advancing both positions would skip a value. If the front values are equal, either may be taken next for numerical ascending order, but both copies must eventually appear in the result. This demonstration takes from the left on equality.
The Python Study demonstration performs one merge of two already sorted lists. It demonstrates the operation used at each merge stage; it does not itself perform the preceding splits. .append(...) adds an item to the end of the new result list. The two final loops copy any remaining items after one source list is exhausted.
Python demonstration: merging two ordered lists
{"code":"left = [1, 3, 6, 8]\nright = [2, 4, 5, 7]\nmerged = []\nleft_index = 0\nright_index = 0\ncomparisons = 0\nwhile left_index < len(left) and right_index < len(right):\n comparisons = comparisons + 1\n if left[left_index] <= right[right_index]:\n merged.append(left[left_index])\n left_index = left_index + 1\n else:\n merged.append(right[right_index])\n right_index = right_index + 1\nwhile left_index < len(left):\n merged.append(left[left_index])\n left_index = left_index + 1\nwhile right_index < len(right):\n merged.append(right[right_index])\n right_index = right_index + 1\nprint('merged =', merged)\nprint('front comparisons =', comparisons)\n","instructions":"Predict the merged list and number of front-item comparisons, then run. Change only right = [2, 4, 5, 7] to right = [9, 10, 11, 12], keeping each source list sorted. Predict which list is exhausted first and the number of front comparisons, then run again. Explain why the remaining items can be appended without more front comparisons."}
Choosing a sorting method
Bubble sort and merge sort can both produce the same sorted data, but they create order through different operations and have different practical advantages.
| Feature | Bubble sort | Merge sort |
|---|---|---|
| Main operation | Compare and swap adjacent items | Split lists, then merge ordered lists |
| Progress towards order | A pass moves a largest remaining item to the right | Each merge builds a larger ordered list |
| Large disordered lists | Many repeated comparisons and swaps can take time | Usually fewer comparisons and less time than bubble sort |
| Already sorted data | A no-swap version can stop after one complete pass | A basic version still splits and merges |
| Implementation | Relatively straightforward loops and swaps | More involved splitting, merging and position tracking |
| Extra storage in these usual versions | A temporary swap value and control variables | Additional lists used while merging |
Merge sort's time advantage on large lists comes from combining ordered smaller lists through a limited number of stages. During a merge, each item is taken once into the result, rather than repeatedly swapping it past neighbors. Bubble sort may need many passes, each making numerous comparisons and swaps.
Bubble sort can be easier to implement and can suit a small list; its no-swap optimisation also helps if the data is already sorted. A usual array merge sort needs additional lists during merging, whereas bubble sort can rearrange the existing array with little extra storage. These are qualitative tradeoffs, not a requirement to calculate formal time or space complexity.
For thousands of regularly sorted records, with enough additional storage available, merge sort is usually a suitable choice because time matters and the larger list makes bubble sort's repeated work costly. For a short classroom list, a simple bubble-sort implementation may be quite adequate. State the reason that fits the task; “merge sort is better” alone does not explain a choice.
Split until the small lists are ordered, then merge by taking the smaller front item. Choose between sorting methods by explaining their work and tradeoffs for the actual data.