Stability, in-place and comparison of sorts
The properties that GATE asks about for every sorting algorithm: stable, in place, adaptive, online, the best, average and worst case and the extra space of bubble, selection, insertion, merge, quick, heap and counting sort; why stability matters, how it is lost, how to restore it, and which sort to choose for which situation.
Why it exists
There is no single best sorting algorithm. Choosing one means asking: how much extra memory is allowed, must equal keys keep their order, is the worst case allowed to be slow, is the input nearly sorted, are the keys small integers? GATE asks these questions in tables: "which of the following is stable?", "which is in place?", "which has the best worst-case time?". This page collects the answers in one place and shows why each is true, so that they can be re-derived instead of memorised.
Prerequisites
You need the three elementary sorts (bubble, selection and insertion sort). The other sorts in the table are proved on their own pages (merge, quick, heap, counting and radix); here only their properties are compared.
Precise definitions
Stable. A sort is stable if, whenever and (equal keys), the record that started at also comes before the record that started at in the output. For records that carry extra data this means: ties are broken by the original order.
In place. The sort uses extra memory besides the input array. (Some texts allow for the recursion stack; GATE usually calls quicksort "in place" and merge sort on arrays "not in place".)
Adaptive. The running time improves when the input is partly sorted (for example insertion sort runs in , the number of inversions).
Online. The sort can accept the keys one at a time and keep the keys seen so far sorted (insertion sort).
Comparison sort. Only uses comparisons between keys, and therefore needs comparisons in the worst case (lower bound). Counting sort and radix sort use the values of the keys and are not comparison sorts.
Internal and external. An internal sort keeps all data in main memory. An external sort handles data that does not fit, and merge sort is its basis because it reads its input sequentially.
How it works
Where stability comes from. A sort is stable when nothing it does can jump a key over an equal one.
- Insertion sort shifts a key past only the keys that are strictly larger (
a[j] > key). The key stops right after an equal key. With>=it would jump over equal keys and become unstable. - Bubble sort swaps only when
a[j] > a[j + 1], never equal neighbours, so equal keys never pass each other. - Merge sort takes from the left half when the two front keys are equal (the code writes the right key only if it is strictly smaller). This is the whole reason it is stable.
- Counting sort places the keys into the output by scanning the input backwards and decreasing the counters, so the last equal key goes to the last free slot.
- Selection sort swaps the minimum with the first unsorted position, a jump over everything in between. Sorting gives . (A version that shifts the elements between instead of swapping is stable, at the cost of moves per pass.)
- Quicksort (array partition) swaps keys across the pivot, over equal keys. Heap sort exchanges the root with the last leaf, then sifts down: also long jumps. Neither is stable.
The table below was produced by running real C implementations of all seven sorts, once on a small set of records and then on every array of up to records with keys from ( arrays per sort), and counting the arrays in which two equal keys came out in a different order. A sort is stable only if that number is zero (and then the argument above proves it for all inputs; a test alone would not). The records show the key, then a letter that marks the original position.
Which sorts keep equal keys in order: start
Computed by a script, not typed| sort | output for 2a 3b 2c 1d 3e 1f | equal keys in input order? | arrays reordered, of all arrays of 1 to 7 keys from {0, 1, 2} | stable? |
|---|---|---|---|---|
| Bubble sort | ||||
| Selection sort (swap) | ||||
| Insertion sort | ||||
| Merge sort | ||||
| Quicksort (last element as pivot) | ||||
| Heap sort | ||||
| Counting sort (backward pass) |
Step 0
Seven sorts were run on the records 2a 3b 2c 1d 3e 1f (key, then a tag showing the original position) and on every array of 1 to 7 records with keys from {0, 1, 2}. A sort is stable if equal keys never change their relative order.
All the properties side by side. The time and space columns are the standard results proved on the pages of the individual sorts; the stable column is the measured one above.
The sorts side by side: start
Computed by a script, not typed| sort | best | average | worst | extra space | stable | in place |
|---|---|---|---|---|---|---|
| Bubble sort (early exit) | ||||||
| Selection sort | ||||||
| Insertion sort | ||||||
| Merge sort (array) | ||||||
| Quicksort | ||||||
| Heap sort | ||||||
| Counting sort |
Step 0
The comparison sorts of the syllabus and counting sort. The stable column is the one measured by running the sorts on every small array (previous table); the time and space columns are the standard results proved on the pages of each sort.
Some remarks that the table cannot fit:
- Quicksort's space. The partition is in place, but the recursion needs a stack: on average, and even in the worst case if the recursive call is made on the smaller part first; otherwise in the worst case.
- Merge sort. On an array it needs a second array of keys. On a linked list it can be done with extra list nodes (and stack) and is still stable.
- Heap sort is the only comparison sort in the table that is both in place and in the worst case. Its drawbacks are that it is not stable and has poor cache behaviour. (If all keys are equal the sift-downs stop at once and the time is linear; the usual statement for GATE is in all cases.)
- Counting sort needs the keys to be integers in a range , time , extra space ; it is stable and not comparison based, so the bound does not apply to it.
- Swaps and writes. Selection sort moves at most records, the fewest; merge sort copies records; insertion and bubble sort move records.
Why stability matters.
- Sorting by several keys. To sort employees by department and, inside each department, by name: sort by name first, then sort by department with a stable sort. The department sort leaves the names inside each department in the order the first sort gave them. With an unstable sort the names inside a department come out in arbitrary order.
- Radix sort sorts by the least significant digit first and then by each more significant digit; it is correct only if every digit pass is stable.
- Any sort can be made stable by adding the original index as a tiebreaker (compare pairs), at the price of extra memory for the indices.
Choosing a sort.
- Guaranteed and stable: merge sort. Costs extra space.
- Guaranteed and space: heap sort. Not stable.
- Fastest on average in practice: quicksort (with a good pivot rule). Worst case , not stable.
- Small or nearly sorted input, or data arriving online: insertion sort.
- Integer keys in a small range: counting sort (or radix sort for larger ranges).
- Expensive record moves: selection sort (fewest moves), or sort pointers to the records.
Worked examples
EX 1Which of these sorts is stable?
EasyRun on the stable sorts give (equal keys in their original order). The measured selection sort output is and quicksort gives the same; heap sort gives . One equal pair in the wrong order is enough to show a sort is not stable. The reverse is not true: a sort can produce the right order on one input and still be unstable (the exhaustive test is what separates them).
EX 2In place or not?
EasyBubble, selection, insertion and heap sort use extra memory: in place. Quicksort uses stack on average: in place in the usual sense. Merge sort on arrays needs a temporary array of keys: not in place. Counting sort needs the count array and an output array: not in place.
EX 3Making selection sort stable
MediumSelection sort picks the first minimum among equal ones, but the swap moves the displaced key to a distant position. Instead of swapping, remove the minimum and insert it at position , shifting the keys one place right. For : the minimum is inserted in front, giving : stable. The result is stable on all test arrays but needs moves per pass, so up to moves, losing the advantage of selection sort (few writes).
EX 4Sorting by two keys
MediumRecords (department, name): . Goal: order by department, ties by name. Step 1: sort by name (stable or not does not matter, names are what we sort): Asha(B), Asha(A), Dev(B), Ravi(A) with the two Ashas in some order. Step 2: stable sort by department: A: Asha, Ravi; B: Asha, Dev (each department keeps the name order of step 1). If step 2 used an unstable sort, could come before . The order of the passes is the least significant key first.
EX 5Choose the algorithm
GATE level(a) A database must sort records with guaranteed time and must not reorder equal keys: merge sort. (b) Embedded device with almost no spare memory, worst-case guarantee needed: heap sort. (c) An array of numbers in which each is at most places from its sorted position, small: insertion sort, . (d) integers all between and : counting sort would take time, worse than comparison sorts, but radix sort with base takes two stable passes of each: overall (linear-time sorts).
Cheat box
Cheat box
- Stable: bubble, insertion, merge, counting (backward pass). Not stable: selection (swap version), quicksort, heap sort.
- In place: bubble, selection, insertion, heap; quicksort ( stack). Not in place: merge (array), counting.
- Worst case : bubble, selection, insertion, quicksort. worst case: merge, heap. Counting: .
- Best case : bubble (flag), insertion. Selection, merge, heap, quicksort: or , never linear (for distinct keys).
- Adaptive: insertion, bubble (flag). Online: insertion.
- Fewest writes: selection sort ( swaps).
- Any sort becomes stable by comparing . Radix sort needs a stable digit sort.
- Comparison sorts need comparisons; counting and radix are not comparison sorts.
Traps and GATE patterns
Connections
Builds on
Across subjects
No cross-subject links yet.
The elementary sorts of this table are in bubble, selection and insertion sort. The fast ones are developed in merge sort, quicksort and heap sort, and the linear-time non-comparison sorts and the bound in lower bound and linear-time sorts.
PYQs
1 previous year question from your book. I re-solved each one myself (1 by running or simulating, 0 by reasoning only); the book's key is shown next to my answer. All PYQs
Assume that the algorithms considered here sort the input sequences in ascending order. If the input is already in ascending order, which of the following are TRUE? I. Quick sort runs in Θ(n2) time II. Bubble sort runs in Θ(n2) time III. Merge sort runs in Θ(n) time IV. Insertion sort runs in Θ(n) time
- (a)I and II only
- (b)I and III only
- (c)II and IV only
- (d)I and IV only ALGORITHMS Check Out Our Gate Courses & Secure Your Dream Rank !
- (a)
Self-check
Question 1
Name the stable sorts among bubble, selection, insertion, merge, quick and heap sort.
Show answerHide
Bubble, insertion and merge sort (with the strict comparisons described). Selection, quick and heap sort are not stable.
Question 2
Which comparison sort is in place and has a worst case?
Show answerHide
Heap sort.
Question 3
How can any sorting algorithm be made stable?
Show answerHide
Attach the original position to each key and compare pairs, so that no two elements are ever equal. This needs extra memory.
Question 4
Why must the digit sort inside radix sort be stable?
Show answerHide
Each pass must keep the order produced by the earlier passes among keys that are equal in the current digit; otherwise the work of the less significant digits is lost.
Revision card
One-screen revision
- Stable: bubble, insertion, merge, counting. Unstable: selection, quick, heap.
- In place: bubble, selection, insertion, heap, quick (stack). Not: merge (array), counting.
- Worst : bubble, selection, insertion, quick. Worst : merge, heap.
- Best : insertion, bubble with flag. Fewest swaps: selection.
- Stability from strict comparison / tie to the left; any sort stable via .
References
- ·Cormen, Leiserson, Rivest, Stein, Introduction to Algorithms (3rd edition), Chapter 8 Sorting in Linear Time (8.2 counting sort, stability) and the chapter introductions of Chapters 2, 6, 7
- ·Sedgewick and Wayne, Algorithms (4th edition), Section 2.5 Applications (stability) and the summary table of Chapter 2
Verification
Stability of the seven sorts was measured by running C implementations on all 3279 arrays of 1 to 7 records with keys from {0, 1, 2} and independently recomputed by a Python implementation (bubble, insertion, merge and counting sort stable; selection, quick and heap sort not stable); a stable variant of selection sort by shifting and the instability of insertion sort with a non-strict comparison were also confirmed. The time and space columns are the standard results proved on the pages of the individual sorts; the heap sort remark about equal keys follows from the sift-down stopping at once on equal keys. Textbook chapter references are from memory. SECOND PASS (2026-11-02, done by the assistant, not a human check): every Self-check question was solved before the printed answer was read and all agreed; the definitions, worked examples, cheat box and traps were read claim by claim and the numbers re-derived by hand or by a small script (loop counts, recurrences, merge and quicksort counts and averages, hash probes and load-factor formulas, DP tables, MST and shortest-path runs, Floyd matrices); long C programs were not re-read line by line (they are compiled and compared by npm run verify:c, and their printed outputs were checked against the prose); tables and animations are machine output and were read, not re-run; No other defect found. Status raised to self-checked; verified needs a textbook or human check.
last verified: never
My notes (saved in this browser)