Introsort or introspective sort is a
hybrid sorting algorithm
In computer science, a sorting algorithm is an algorithm that puts elements of a List (computing), list into an Total order, order. The most frequently used orders are numerical order and lexicographical order, and either ascending or descending ...
that provides both fast average performance and (asymptotically) optimal worst-case performance. It begins with
quicksort
Quicksort is an efficient, general-purpose sorting algorithm. Quicksort was developed by British computer scientist Tony Hoare in 1959 and published in 1961. It is still a commonly used algorithm for sorting. Overall, it is slightly faster than ...
, it switches to
heapsort
In computer science, heapsort is an efficient, comparison-based sorting algorithm that reorganizes an input array into a heap (a data structure where each node is greater than its children) and then repeatedly removes the largest node from that ...
when the recursion depth exceeds a level based on (the
logarithm
In mathematics, the logarithm of a number is the exponent by which another fixed value, the base, must be raised to produce that number. For example, the logarithm of to base is , because is to the rd power: . More generally, if , the ...
of) the number of elements being sorted and it switches to
insertion sort
Insertion sort is a simple sorting algorithm that builds the final sorted array (or list) one item at a time by comparisons. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. Howev ...
when the number of elements is below some threshold. This combines the good parts of the three algorithms, with practical performance comparable to quicksort on typical data sets and worst-case
O(''n'' log ''n'') runtime due to the heap sort. Since the three algorithms it uses are
comparison sorts, it is also a comparison sort.
Introsort was invented by
David Musser in , in which he also introduced
introselect, a hybrid
selection algorithm based on
quickselect (a variant of quicksort), which falls back to
median of medians and thus provides worst-case linear complexity, which is optimal. Both algorithms were introduced with the purpose of providing
generic algorithms for the
C++ Standard Library
The C standard library, sometimes referred to as libc, is the standard library for the C programming language, as specified in the ISO C standard.ISO/ IEC (2018). '' ISO/IEC 9899:2018(E): Programming Languages - C §7'' Starting from the origina ...
which had both fast average performance and optimal worst-case performance, thus allowing the performance requirements to be tightened. Introsort is
in-place and a non-
stable
A stable is a building in which working animals are kept, especially horses or oxen. The building is usually divided into stalls, and may include storage for equipment and feed.
Styles
There are many different types of stables in use tod ...
algorithm.
Pseudocode
If a heapsort implementation and partitioning functions of the type discussed in the
quicksort
Quicksort is an efficient, general-purpose sorting algorithm. Quicksort was developed by British computer scientist Tony Hoare in 1959 and published in 1961. It is still a commonly used algorithm for sorting. Overall, it is slightly faster than ...
article are available, the introsort can be described succinctly as
procedure sort(A : array):
maxdepth ← ⌊log
2(length(A))⌋ × 2
introsort(A, maxdepth)
procedure introsort(A, maxdepth):
n ← length(A)
if n < 16:
insertionsort(A)
else if maxdepth = 0:
heapsort(A)
else:
p ← partition(A) ''// assume this function does pivot selection, p is the final position of the pivot''
introsort(A
:p-1 maxdepth - 1)
introsort(A
+1:n maxdepth - 1)
The factor 2 in the maximum depth is arbitrary; it can be tuned for practical performance. denotes the
array slice of items to including both and . The indices are assumed to start with 1 (the first element of the array is ).
Analysis
In quicksort, one of the critical operations is choosing the pivot: the element around which the list is partitioned. The simplest pivot selection algorithm is to take the first or the last element of the list as the pivot, causing poor behavior for the case of sorted or nearly sorted input.
Niklaus Wirth
Niklaus Emil Wirth ( IPA: ) (15 February 1934 – 1 January 2024) was a Swiss computer scientist. He designed several programming languages, including Pascal, and pioneered several classic topics in software engineering. In 1984, he won the Tu ...
's variant uses the middle element to prevent these occurrences, degenerating to O(''n''
2) for contrived sequences. The median-of-3 pivot selection algorithm takes the median of the first, middle, and last elements of the list; however, even though this performs well on many real-world inputs, it is still possible to contrive a ''median-of-3 killer'' list that will cause dramatic slowdown of a quicksort based on this pivot selection technique.
Musser reported that on a median-of-3 killer sequence of 100,000 elements, introsort's running time was 1/200 that of median-of-3 quicksort. Musser also considered the effect on
caches of
Sedgewick's delayed small sorting, where small ranges are sorted at the end in a single pass of
insertion sort
Insertion sort is a simple sorting algorithm that builds the final sorted array (or list) one item at a time by comparisons. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. Howev ...
. He reported that it could double the number of cache misses, but that its performance with
double-ended queues was significantly better and should be retained for template libraries, in part because the gain in other cases from doing the sorts immediately was not great.
Implementations
Introsort or some variant is used in a number of
standard library
In computer programming, a standard library is the library (computing), library made available across Programming language implementation, implementations of a programming language. Often, a standard library is specified by its associated program ...
sort functions, including some
C++ sort implementations.
The June 2000
SGI C++
Standard Template Library
The Standard Template Library (STL) is a software library originally designed by Alexander Stepanov for the C++ programming language that influenced many parts of the C++ Standard Library. It provides four components called ''algorithms'', '' ...
br>
stl_algo.himplementation of
unstable sort uses the Musser introsort approach with the recursion depth to switch to heapsort passed as a parameter, median-of-3 pivot selection and the Knuth final insertion sort pass for partitions smaller than 16.
The
GNU Standard C++ library
GNU ( ) is an extensive collection of free software (394 packages ), which can be used as an operating system or can be used in parts with other operating systems. The use of the completed GNU tools led to the family of operating systems popu ...
is similar: uses introsort with a maximum depth of 2×log
2 ''n'', followed by an
insertion sort
Insertion sort is a simple sorting algorithm that builds the final sorted array (or list) one item at a time by comparisons. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. Howev ...
on partitions smaller than 16.
LLVM libc++ also uses introsort with a maximum depth of 2×log
2 ''n'', however the size limit for
insertion sort
Insertion sort is a simple sorting algorithm that builds the final sorted array (or list) one item at a time by comparisons. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. Howev ...
is different for different data types (30 if swaps are trivial, 6 otherwise). Also, arrays with sizes up to 5 are handled separately. Kutenin (2022) provides an overview for some changes made by LLVM, with a focus on the 2022 fix for quadraticness.
The
Microsoft .NET Framework Class Library, starting from version 4.5 (2012), uses introsort instead of simple quicksort.
Go uses a modification of introsort: for slices of 12 or less elements it uses
insertion sort
Insertion sort is a simple sorting algorithm that builds the final sorted array (or list) one item at a time by comparisons. It is much less efficient on large lists than more advanced algorithms such as quicksort, heapsort, or merge sort. Howev ...
, and for larger slices it uses
pattern-defeating quicksort and more advanced median of three medians for pivot selection. Prior to version 1.19 it used shell sort for small slices.
Java
Java is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea (a part of Pacific Ocean) to the north. With a population of 156.9 million people (including Madura) in mid 2024, proje ...
, starting from version 14 (2020), uses a hybrid sorting algorithm that uses merge sort for highly structured arrays (arrays that are composed of a small number of sorted subarrays) and introsort otherwise to sort arrays of ints, longs, floats and doubles.
Variants
pdqsort
Pattern-defeating quicksort (pdqsort) is a variant of introsort developed by Orson Peters, incorporating the following improvements:
* Median-of-three pivoting,
* "BlockQuicksort" partitioning technique to mitigate branch misprediction penalities,
* Linear time performance for certain input patterns (
adaptive sort),
* Use element shuffling on bad cases before trying the slower heapsort.
* Improved adaptivity for low-cardinality inputs
Pdqsort is used by
Rust
Rust is an iron oxide, a usually reddish-brown oxide formed by the reaction of iron and oxygen in the catalytic presence of water or air moisture. Rust consists of hydrous iron(III) oxides (Fe2O3·nH2O) and iron(III) oxide-hydroxide (FeO(OH) ...
,
GAP, and the C++ library
Boost.
fluxsort
fluxsort is a stable variant of introsort incorporating the following improvements:
* branchless sqrt(n) pivoting
* Flux partitioning technique for stable partially-in-place partitioning
* Significantly improved smallsort by utilizing branchless bi-directional parity merges
* A fallback to quadsort, a branchless bi-directional mergesort, significantly increasing adaptivity for ordered inputs
Improvements introduced by fluxsort and its unstable variant, crumsort, were adopted by crumsort-rs, glidesort, ipnsort, and driftsort. The overall performance increase on random inputs compared to pdqsort is around 50%.
References
General
*
* Niklaus Wirth. ''Algorithms and Data Structures''. Prentice-Hall, Inc., 1985. .
{{sorting
Comparison sorts
Articles with example pseudocode