Hubbry Logo
search
logo
994048

Bubble sort

logo
Community Hub0 Subscribers
Read side by side
from Wikipedia
Bubble sort
Static visualization of bubble sort[1]
ClassSorting algorithm
Data structureArray
Worst-case performance comparisons, swaps
Best-case performance comparisons, swaps
Average performance comparisons, swaps
Worst-case space complexity total, auxiliary
OptimalNo

Bubble sort, sometimes referred to as sinking sort, is a simple sorting algorithm that repeatedly steps through the input list element by element, comparing the current element with the one after it, swapping their values if needed. These passes through the list are repeated until no swaps have to be performed during a pass, meaning that the list has become fully sorted. The algorithm, which is a comparison sort, is named for the way the larger elements "bubble" up to the top of the list.

It performs poorly in real-world use and is used primarily as an educational tool. More efficient algorithms such as quicksort, timsort, or merge sort are used by the sorting libraries built into popular programming languages such as Python and Java.[2][3]

History

[edit]

The earliest description of the bubble sort algorithm was in a 1956 paper by mathematician and actuary Edward Harry Friend,[4] Sorting on electronic computer systems,[5] published in the third issue of the third volume of the Journal of the Association for Computing Machinery (ACM), as a "Sorting exchange algorithm." Friend described the fundamentals of the algorithm, and although initially his paper went unnoticed, some years later it was rediscovered by many computer scientists, including Kenneth E. Iverson, who coined its current name.

Analysis

[edit]
An example of bubble sort. Starting from the beginning of the list, compare every adjacent pair, swapping their position if they are not in the right order (the latter one is smaller than the former one). After each iteration, one less element (the last one) needs to be compared until there are no more elements left to be compared.

Performance

[edit]

Bubble sort has a worst-case and average complexity of , where is the number of items being sorted. Most practical sorting algorithms have substantially better worst-case or average complexity, often . Even other sorting algorithms, such as insertion sort, generally run faster than bubble sort, and are no more complex. For this reason, bubble sort is rarely used in practice.

Like insertion sort, bubble sort is adaptive, which can give it an advantage over algorithms like quicksort. This means that it may outperform those algorithms in cases where the list is already mostly sorted (having a small number of inversions), despite the fact that it has worse average-case time complexity. For example, bubble sort is on a list that is already sorted, while quicksort would still perform its entire sorting process.

While any sorting algorithm can be made on a presorted list simply by checking the list before the algorithm runs, improved performance on almost-sorted lists is harder to replicate.

Rabbits and turtles

[edit]

The distance and direction that elements must move during the sort determine bubble sort's performance because elements move in different directions at different speeds. An element that must move toward the end of the list can move quickly because it can take part in successive swaps. For example, the largest element in the list will win every swap, so it moves to its sorted position on the first pass even if it starts near the beginning. On the other hand, an element that must move toward the beginning of the list cannot move faster than one step per pass, so elements move toward the beginning very slowly. If the smallest element is at the end of the list, it will take passes to move it to the beginning. This has led to these types of elements being named rabbits and turtles, respectively, after the characters in Aesop's fable of The Tortoise and the Hare.

Various efforts have been made to eliminate turtles to improve the speed of bubble sort. Cocktail sort is a bi-directional bubble sort that goes from beginning to end, and then reverses itself, going end to beginning. It can move turtles fairly well, but it retains worst-case complexity. Comb sort compares elements separated by large gaps, and can move turtles extremely quickly before proceeding to smaller and smaller gaps to smooth out the list. Its average speed is comparable to faster algorithms like quicksort.

Step-by-step example

[edit]

Take an array of numbers "5 1 4 2 8", and sort the array from lowest number to greatest number using bubble sort. In each step, elements written in bold are being compared. Three passes will be required:

First pass
( 5 1 4 2 8 ) → ( 1 5 4 2 8 ), Here, algorithm compares the first two elements, and swaps since 5 > 1.
( 1 5 4 2 8 ) → ( 1 4 5 2 8 ), Swap since 5 > 4
( 1 4 5 2 8 ) → ( 1 4 2 5 8 ), Swap since 5 > 2
( 1 4 2 5 8 ) → ( 1 4 2 5 8 ), Now, since these elements are already in order (8 > 5), algorithm does not swap them.
Second pass
( 1 4 2 5 8 ) → ( 1 4 2 5 8 )
( 1 4 2 5 8 ) → ( 1 2 4 5 8 ), Swap since 4 > 2
( 1 2 4 5 8 ) → ( 1 2 4 5 8 )
( 1 2 4 5 8 ) → ( 1 2 4 5 8 )

Now, the array is already sorted, but the algorithm does not know if it is completed. The algorithm needs one additional whole pass without any swap to know it is sorted.

Third pass
( 1 2 4 5 8 ) → ( 1 2 4 5 8 )
( 1 2 4 5 8 ) → ( 1 2 4 5 8 )
( 1 2 4 5 8 ) → ( 1 2 4 5 8 )
( 1 2 4 5 8 ) → ( 1 2 4 5 8 )

Implementation

[edit]

Pseudocode implementation

[edit]

In pseudocode the algorithm can be expressed as (0-based array):

procedure bubbleSort(A : list of sortable items)
    n := length(A)
    repeat
        swapped := false
        for i := 1 to n-1 inclusive do
            { if this pair is out of order }
            if A[i-1] > A[i] then
                { swap them and remember something changed }
                swap(A[i-1], A[i])
                swapped := true
            end if
        end for
    until not swapped
end procedure

Optimizing bubble sort

[edit]

The bubble sort algorithm can be optimized by observing that the n-th pass finds the n-th largest element and puts it into its final place. So, the inner loop can avoid looking at the last n − 1 items when running for the n-th time:

procedure bubbleSort(A : list of sortable items)
    n := length(A)
    repeat
        swapped := false
        for i := 1 to n - 1 inclusive do
            if A[i - 1] > A[i] then
                swap(A[i - 1], A[i])
                swapped := true
            end if
        end for
        n := n - 1
    until not swapped
end procedure

More generally, it can happen that more than one element is placed in its final position on a single pass. In particular, after every pass, all elements after the last swap are sorted, and do not need to be checked again. This allows us to skip over many elements, resulting in about a 50% improvement in the worst-case comparison count (though no improvement in swap counts), and adds very little complexity because the new code subsumes the swapped variable:

To accomplish this in pseudocode, the following can be written:

procedure bubbleSort(A : list of sortable items)
    n := length(A)
    repeat
        newn := 0
        for i := 1 to n - 1 inclusive do
            if A[i - 1] > A[i] then
                swap(A[i - 1], A[i])
                newn := i
            end if
        end for
        n := newn
    until n  1
end procedure

Alternate modifications, such as the cocktail shaker sort attempt to improve on the bubble sort performance while keeping the same idea of repeatedly comparing and swapping adjacent items.

Use

[edit]
Bubble sort. The list was plotted in a Cartesian coordinate system, with each point (x, y) indicating that the value y is stored at index x. Then the list would be sorted by bubble sort according to every pixel's value. Note that the largest end gets sorted first, with smaller elements taking longer to move to their correct positions.

Although bubble sort is one of the simplest sorting algorithms to understand and implement, its O(n2) complexity means that its efficiency decreases dramatically on lists of more than a small number of elements. Even among simple O(n2) sorting algorithms, algorithms like insertion sort are usually considerably more efficient.

Due to its simplicity, bubble sort is often used to introduce the concept of an algorithm, or a sorting algorithm, to introductory computer science students. However, some educators such as Owen Astrachan have gone to great lengths to disparage bubble sort and its continued popularity in computer science education, recommending that it no longer even be taught.[6]

The Jargon File, which famously calls bogosort "the archetypical [sic] perversely awful algorithm", also calls bubble sort "the generic bad algorithm".[7] Donald Knuth, in The Art of Computer Programming, concluded that "the bubble sort seems to have nothing to recommend it, except a catchy name and the fact that it leads to some interesting theoretical problems", some of which he then discusses.[8]

Bubble sort is asymptotically equivalent in running time to insertion sort in the worst case, but the two algorithms differ greatly in the number of swaps necessary. Experimental results such as those of Astrachan have also shown that insertion sort performs considerably better even on random lists. For these reasons, many modern algorithm textbooks avoid using the bubble sort algorithm in favor of insertion sort.

Bubble sort also interacts poorly with modern CPU hardware. It produces at least twice as many writes as insertion sort, twice as many cache misses, and asymptotically more branch mispredictions.[citation needed] Experiments by Astrachan sorting strings in Java show bubble sort to be roughly one-fifth as fast as an insertion sort and 70% as fast as a selection sort.[6]

In computer graphics, bubble sort is popular for its capability to detect a very small error (like a swap of just two elements) in almost-sorted arrays and fix it with just linear complexity (2n). For example, it is used in a polygon filling algorithm, where bounding lines are sorted by their x coordinate at a specific scan line (a line parallel to the x axis), and with incrementing y, their order changes (two elements are swapped) only at intersections of two lines. Bubble sort is a stable sort algorithm, like insertion sort.

Variations

[edit]
  • Odd–even sort is a parallel version of bubble sort, for message-passing systems.
  • Passes can be from right to left, rather than left to right. This is more efficient for lists with unsorted items added to the end.
  • Cocktail shaker sort alternates leftwards and rightwards passes.

Debate over name

[edit]

Bubble sort has been occasionally referred to as a "sinking sort".[9]

For example, Donald Knuth describes the insertion of values at or towards their desired location as letting "[the value] settle to its proper level", and that "this method of sorting has sometimes been called the sifting or sinking technique.[10]

This debate is perpetuated by the ease with which one may consider this algorithm from two different but equally valid perspectives:

  1. The larger values might be regarded as heavier and therefore be seen to progressively sink to the bottom of the list
  2. The smaller values might be regarded as lighter and therefore be seen to progressively bubble up to the top of the list.
[edit]

In a 2007 interview, former Google CEO Eric Schmidt asked then-presidential candidate Barack Obama about the best way to sort one million integers; Obama paused for a moment and replied: "I think the bubble sort would be the wrong way to go."[11][12]

Notes

[edit]

References

[edit]
[edit]
Revisions and contributorsEdit on WikipediaRead on Wikipedia
from Grokipedia
Bubble sort is a simple comparison-based sorting algorithm that repeatedly iterates through an unsorted list, comparing adjacent elements and swapping them if they are in the wrong order, thereby gradually moving larger elements toward the end of the list in each pass, like bubbles rising to the surface.[1][2] The process continues for multiple passes until no further swaps are required, indicating the list is fully sorted.[3] The algorithm's origins trace back to at least 1956, when a variant was described in a thesis as a "filing scheme for establishing... sort order," though the term "bubble sort" first appeared in print in 1962, coined by Kenneth E. Iverson in reference to the way elements "bubble" to their correct positions.[4][5] Despite its simplicity, bubble sort has persisted in educational contexts as an introductory example of sorting, even as more efficient algorithms have been developed, due to its straightforward implementation and intuitive visualization of the sorting process.[6][7] In terms of performance, bubble sort has a time complexity of O(n²) in the worst and average cases, where n is the number of elements, due to the nested loops that perform up to n passes, each involving up to n comparisons and swaps.[8][9] The best-case time complexity is O(n) when the list is already sorted, as an early termination optimization can detect no swaps after a single pass.[8] Its space complexity is O(1), making it an in-place algorithm that requires no additional storage beyond the input array.[3][8] Bubble sort is stable, preserving the relative order of equal elements, which is a desirable property in certain applications like sorting records with secondary keys.[3] However, its quadratic time complexity renders it inefficient for large datasets compared to advanced algorithms like quicksort or mergesort, limiting its practical use to small lists or pedagogical demonstrations.[9][10] Variants, such as cocktail shaker sort, extend the basic approach by traversing the list in both directions to potentially reduce passes.

Algorithm Description

Core Mechanism

Bubble sort is a simple comparison-based sorting algorithm that operates by repeatedly traversing a list of elements, comparing adjacent pairs, and swapping them if they are in the incorrect order relative to the desired sorting direction, such as ascending or descending.[8] This process ensures that misplaced elements gradually move toward their correct positions through successive iterations. The algorithm assumes the input is an array or list of comparable elements, such as integers or other data types that support a total ordering, and requires no prior knowledge of the data's sorted state.[11] The name "bubble sort" derives from the "bubbling" effect observed during execution, where the largest (in ascending sort) or smallest (in descending sort) elements progressively rise to the end of the list, akin to bubbles rising in a liquid.[12] In each traversal, an element that is out of place will be swapped multiple times with its neighbors until it reaches its appropriate position at the boundary of the unsorted portion, simulating this upward movement. This mechanism relies solely on pairwise comparisons and adjacent swaps, making it straightforward but inefficient for large datasets, with a quadratic time complexity that is explored in greater detail elsewhere.[11] The algorithm's structure involves an outer loop that controls the number of passes through the list, typically iterating n-1 times for a list of n elements, as each pass positions one more element correctly at the end.[13] Within each outer iteration, an inner loop performs the comparisons and swaps, starting from the beginning of the list and proceeding up to the last unsorted index, which decreases by one after each pass to avoid re-examining the already sorted suffix. This reduction in the inner loop's range ensures that only the unsorted portion is processed in subsequent passes, optimizing the comparisons without altering the core logic.[14]

Step-by-Step Example

To illustrate the bubble sort algorithm, consider the following unsorted array of five elements: [5, 3, 8, 4, 2]. The process involves repeated passes over the array, where in each pass, adjacent elements are compared from left to right, and any pair that is out of order (with the larger element preceding the smaller one) is swapped. This "bubbling" action gradually moves larger elements toward the end of the array.[8] The table below shows the state of the array after each comparison and swap during the passes. For an array of n = 5 elements, the algorithm requires up to n-1 = 4 passes, though it can potentially terminate early if the array becomes fully sorted before completing all passes. In this example, swaps occur in every pass until the array is sorted.
PassComparisons and SwapsArray State After Pass
Initial-[5, 3, 8, 4, 2]
1 (largest element bubbles to end)- Compare indices 0-1: 5 > 3, swap → [3, 5, 8, 4, 2]
- Compare indices 1-2: 5 < 8, no swap
- Compare indices 2-3: 8 > 4, swap → [3, 5, 4, 8, 2]
- Compare indices 3-4: 8 > 2, swap → [3, 5, 4, 2, 8]
[3, 5, 4, 2, 8]
2 (second-largest bubbles to second-last position)- Compare indices 0-1: 3 < 5, no swap
- Compare indices 1-2: 5 > 4, swap → [3, 4, 5, 2, 8]
- Compare indices 2-3: 5 > 2, swap → [3, 4, 2, 5, 8]
[3, 4, 2, 5, 8]
3 (third-largest bubbles to third-last position)- Compare indices 0-1: 3 < 4, no swap
- Compare indices 1-2: 4 > 2, swap → [3, 2, 4, 5, 8]
[3, 2, 4, 5, 8]
4 (remaining elements sorted)- Compare indices 0-1: 3 > 2, swap → [2, 3, 4, 5, 8][2, 3, 4, 5, 8] (sorted)
After the first pass, the largest element (8) reaches its final position at the end. In subsequent passes, the process repeats on the unsorted prefix of the array, ensuring the second-largest (5), third-largest (4), and so on, progressively move to their correct positions. By the final pass, the entire array is sorted in ascending order.[8]

Analysis

Time and Space Complexity

Bubble sort exhibits a time complexity of O(n2)O(n^2) in both the worst and average cases, where nn is the number of elements in the array, as it performs n(n1)2\frac{n(n-1)}{2} comparisons regardless of the input arrangement.[15] This arises from the nested loop structure: the outer loop iterates n1n-1 times (from i=0i = 0 to n2n-2), and the inner loop executes ni1n - i - 1 comparisons per iteration of the outer loop.[15] The total number of comparisons is thus given by the summation
i=0n2(ni1)=k=1n1k=n(n1)2, \sum_{i=0}^{n-2} (n - i - 1) = \sum_{k=1}^{n-1} k = \frac{n(n-1)}{2},
which is Θ(n2)\Theta(n^2).[15] In the worst case, the number of swaps also reaches this upper bound of n(n1)2\frac{n(n-1)}{2}, occurring when the input is in reverse order.[15] In the best case, with a sorted input, bubble sort achieves O(n)O(n) time complexity, as no swaps are needed and early termination can be applied after a single pass.[15] Regarding space complexity, bubble sort requires O(1)O(1) auxiliary space, operating in-place on the input array without needing additional data structures beyond a few constant variables for indexing and swapping.[15]

Performance Behaviors

Bubble sort is a stable sorting algorithm, meaning it preserves the relative order of elements with equal keys in the input array. This property arises because the algorithm only performs swaps between adjacent elements that are out of order, ensuring that equal elements are never swapped unnecessarily.[16][3] The algorithm exhibits partial adaptivity in that it can complete fewer passes through nearly sorted data when implemented with an early termination flag that checks for swaps in each pass; however, the basic version without such a flag remains quadratic in time complexity regardless of input order.[16][17] As an in-place sorting method, bubble sort requires no additional memory proportional to the input size beyond a constant amount for variables like indices and flags, making it suitable for environments with limited memory availability.[3][18] Despite these traits, bubble sort suffers from significant drawbacks in efficiency, including a high number of unnecessary comparisons even when the input is already sorted, as it always performs a fixed number of passes without early stopping. Additionally, its repeated traversals can lead to suboptimal cache performance in modern hardware due to the pattern of accesses, though its adjacent swaps maintain some locality.[19][20]

Rabbits and Turtles Effect

In bubble sort, the rabbits and turtles effect describes the asymmetric movement patterns of elements during sorting, particularly evident in random input permutations. Rabbits refer to large elements positioned near the beginning of the array, which rapidly "bubble" to the right toward their final positions through successive swaps in early passes. In contrast, turtles denote small elements located near the end, which advance leftward slowly, often requiring nearly as many passes as the array length to reach the front.[21] This phenomenon arises from the algorithm's pairwise adjacent comparisons and swaps, where each pass fixes the largest unsorted element at the end but only shifts smaller elements one position leftward per iteration. According to Donald E. Knuth's analysis in random permutations, large elements tend to travel far to the right early in the process, as they participate in multiple swaps during initial passes, while small elements lag behind, often remaining misplaced until later stages.[22] For instance, in a conceptual random array of length nn, the largest element starting at the beginning may undergo up to n1n-1 rightward swaps across the first pass alone if it is larger than all succeeding elements, yet smaller elements' progress remains gradual over subsequent passes. The rabbits and turtles effect contributes to bubble sort's inefficiency by elevating the total number of swaps beyond what might be expected from uniform element movement, as turtles necessitate additional full passes to resolve their positions. This pattern exacerbates the quadratic time complexity in average cases for random data, highlighting why variants like cocktail sort address turtles by incorporating reverse passes.[23]

Implementation

Pseudocode

The standard pseudocode for the unoptimized bubble sort algorithm, which sorts an array of comparable elements in ascending order, is presented below. This formulation uses nested loops to iteratively compare and swap adjacent elements that are out of order, ensuring larger elements progressively "bubble" toward the end of the array.[24][25]
procedure bubbleSort(arr: array of integers, n: integer)
    for i from 0 to n-2 do
        for j from 0 to n-i-2 do
            if arr[j] > arr[j+1] then
                swap arr[j] and arr[j+1]
            end if
        end for
    end for
end procedure
The outer loop, indexed by i from 0 to n-2, represents the n-1 passes through the array, where each pass fixes the position of the next largest element at the end.[24] The inner loop, indexed by j from 0 to n-i-2, performs adjacent pairwise comparisons and potential swaps up to the unsorted portion of the array, reducing the comparison range by one element per outer iteration to avoid redundant work on already-sorted suffixes and to prevent accessing an out-of-bounds index when comparing arr[j] and arr[j+1].[25][26] This pseudocode assumes 0-based indexing for the array and sorts elements in non-decreasing (ascending) order by using the strict greater-than (>) comparison, which only swaps when necessary.[24] It is stable, meaning that equal elements maintain their relative order since swaps occur only for strictly unequal adjacent pairs, preserving the original sequence of duplicates.[3] The algorithm can be adapted for descending order by replacing the > operator with < in the comparison.[27]

Language-Specific Examples

Bubble sort implementations in popular programming languages closely follow the abstract pseudocode structure, adapting to each language's syntax for data structures, loops, and element swapping. These examples demonstrate unoptimized versions that perform full passes regardless of early sorting, focusing on integer arrays or lists for clarity.

Python

Python's dynamic typing and built-in list support enable concise implementations without explicit type declarations or size parameters beyond the list length. Swapping uses tuple assignment, which is efficient and readable.
def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        for j in range(0, n - i - 1):
            if arr[j] > arr[j + 1]:
                arr[j], arr[j + 1] = arr[j + 1], arr[j]
This function modifies the input list in place and returns nothing, aligning with Python's emphasis on mutable sequences.[10] A common implementation mistake is using range(0, n - i) for the inner loop instead of range(0, n - i - 1). This causes the loop to iterate one too many times, resulting in an IndexError when attempting to access arr[j + 1] where j reaches n - i - 1 and j + 1 equals n - i, which is out of bounds. For example, with n=5 and i=0, j goes to 4, trying to compare arr[4] and arr[5], but index 5 does not exist.[26]

C++

In C++, arrays require explicit sizing and pointer handling, with the <algorithm> header providing std::swap for safe element exchange. The function operates on a fixed-size array passed by pointer, ensuring no bounds issues within the loops.
#include <algorithm>  // for std::swap

void bubbleSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                std::swap(arr[j], arr[j + 1]);
            }
        }
    }
}
Static typing in C++ demands careful array management, differing from dynamic languages, and the void return type indicates in-place modification.[28]

Java

Java's fixed-size arrays and object-oriented paradigm require length access via .length, with manual temporary variables for swapping to avoid built-in utilities in basic implementations. The static method suits utility classes for sorting.
public static void bubbleSort(int[] arr) {
    int n = arr.length;
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}
Like C++, Java enforces static typing but includes automatic garbage collection, simplifying memory handling compared to manual allocation in C++.[11] These examples illustrate key language differences: Python prioritizes simplicity with dynamic structures, while C++ and Java emphasize explicit control over static arrays, all achieving in-place sorting without additional space beyond the input.

Optimizations and Variations

Standard Optimizations

One common optimization to the basic bubble sort algorithm involves reducing the range of the inner loop in each pass. After the ith pass, the last i elements are guaranteed to be in their correct sorted positions, so subsequent passes need only compare and swap up to the unsorted portion of the array, specifically from index 0 to n-i-2. This adjustment halves the number of comparisons in the unoptimized version, changing the total from (n-1)^2 to n(n-1)/2 for the worst case.[29] The following pseudocode illustrates this reduced inner loop:
for i from 0 to n-2:
    for j from 0 to n-i-2:
        if array[j] > array[j+1]:
            swap array[j] and array[j+1]
This optimization is inherent to the standard formulation of bubble sort and focuses on eliminating redundant checks on already-sorted suffixes.[17] A further enhancement introduces a boolean flag, often named "swapped," to enable early termination. At the start of each outer loop iteration, the flag is set to false; it is then set to true whenever a swap occurs in the inner loop. If the flag remains false after a full pass—indicating no swaps were needed—the array is fully sorted, and the algorithm can exit immediately. This prevents unnecessary passes over sorted data. The modified pseudocode incorporating both the reduced inner loop and the swapped flag is:
swapped = true
i = 0
while i < n-1 and swapped:
    swapped = false
    for j from 0 to n-i-2:
        if array[j] > array[j+1]:
            swap array[j] and array[j+1]
            swapped = true
    i = i + 1
This flag-based approach is widely adopted in educational and practical implementations to improve efficiency on partially sorted inputs.[17][29] Another standard tweak is the cocktail shaker sort, a bidirectional variant that alternates passes from left-to-right and right-to-left to bubble both large and small elements toward their positions more quickly; however, its full mechanics are covered among notable variants.[5][30] These optimizations yield a best-case time complexity of O(n) for already sorted arrays due to early termination after one pass, while the average- and worst-case complexities remain O(n²), offering only marginal improvements for random inputs. Space complexity stays O(1) as an in-place algorithm.[31][17]

Notable Variants

Cocktail shaker sort, also known as bidirectional bubble sort or shaker sort, extends the basic bubble sort by alternating the direction of comparison passes: one pass proceeds from the beginning to the end of the array (bubbling larger elements to the right), followed by a reverse pass from end to beginning (bubbling smaller elements to the left). This bidirectional traversal reduces the number of passes required compared to standard bubble sort, particularly in cases with elements that are far from their final positions, while maintaining the same O(n²) time complexity. The variant was described by Donald E. Knuth in his analysis of sorting algorithms, where it is presented as a refinement to improve element mobility in both directions.[30] Odd-even sort, or odd-even transposition sort, is a parallelizable variant of bubble sort designed for concurrent processing environments, such as processor arrays or networks. It operates in alternating phases: in the odd phase, comparisons and swaps occur between elements at odd-even index pairs (e.g., positions 1-2, 3-4), while the even phase compares even-odd pairs (e.g., 2-3, 4-5); this process repeats for n passes to ensure sorting. This structure allows independent comparisons in each phase, making it suitable for parallel execution on systems with local interconnections, though it retains O(n²) sequential complexity. The algorithm was formalized for parallel architectures in early studies on multi-microprocessor implementations.[32] Comb sort improves upon bubble sort by introducing a variable gap size for comparisons, starting with a large gap (often n / 1.3) and shrinking it iteratively toward 1, akin to an initial phase of shell sort followed by bubble sort. This gap mechanism effectively addresses the "turtles" problem—small elements trapped near the end of the array—by enabling distant swaps early, leading to faster propagation of misplaced elements. Like its predecessors, it has O(n²) worst-case time complexity but performs better on average for random inputs due to reduced inversions handled per pass. The algorithm was originally proposed by Włodzimierz Dobosiewicz as an efficient bubble sort variation. In comparison, cocktail shaker sort excels at balancing forward and backward movement to minimize passes in linear arrangements, odd-even sort prioritizes parallelism for hardware or distributed systems, and comb sort targets inefficiency from distant inversions through gap-based skipping, each adapting bubble sort's core exchange principle to specific performance bottlenecks.

History and Naming

Origins and Development

The bubble sort algorithm emerged in the early days of electronic computing as a simple exchange-based sorting method, with its conceptual roots in rudimentary data organization techniques of the 1950s. The earliest documented analysis of the core mechanism—repeatedly swapping adjacent elements to "bubble" larger values to the end—appeared in 1956, when Edward H. Friend described it as "sorting by exchange" in his paper "Sorting on Electronic Computer Systems," published in the Journal of the Association for Computing Machinery. Friend's work focused on practical implementations for early computers like the UNIVAC, highlighting the algorithm's simplicity despite its limitations in efficiency for large datasets. This description built on prior informal exchange sorts but formalized the pairwise comparison and swap process that defines bubble sort today. By the late 1950s, the algorithm gained further traction in computing literature under names like "exchange sorting." In 1959, Daniel D. McCracken, Harold Weiss, and Tae H. Lee included a variant in their textbook Programming Business Computers, presenting it as an accessible method for business applications on early machines such as the IBM 650, emphasizing its ease of coding without requiring complex data structures. The explicit term "bubble sort" first appeared in print in 1962, coined by Kenneth E. Iverson in his influential book A Programming Language, where he used it to describe the iterative bubbling of elements in array-based sorting within the context of his APL notation. This naming reflected the visual analogy of lighter elements rising like bubbles in a liquid, and it quickly entered technical discourse. In 1963, a related shuttle variant was formalized as Algorithm 175, "Shuttle Sort," in the Communications of the ACM, further disseminating the approach among programmers.[33] The algorithm's development accelerated in the 1960s and 1970s through its adoption in educational and practical settings, owing to its minimal memory requirements and straightforward logic suited to resource-constrained early computers. In 1971, William A. Martin surveyed sorting methods in ACM Computing Surveys and praised bubble sort for its pedagogical value, noting its utility in teaching fundamental comparison-based sorting without advanced optimizations. This endorsement contributed to its widespread inclusion in introductory computer science curricula. By 1973, Donald E. Knuth analyzed it extensively in the first edition of The Art of Computer Programming, Volume 3: Sorting and Searching, where he critiqued its quadratic time complexity but acknowledged its historical role and simplicity, solidifying its place in algorithmic literature despite warnings of inefficiency. In 1974, Alfred V. Aho, John E. Hopcroft, and Jeffrey D. Ullman recommended it in The Design and Analysis of Computer Algorithms for small-scale sorting tasks on limited hardware, underscoring its enduring appeal for teaching and prototyping on simple systems. These contributions marked bubble sort's evolution from an obscure exchange method to a staple in computing education.

Debate Over Terminology

The term "bubble sort" originated in 1962 when Kenneth E. Iverson introduced it in his book [A Programming Language](/page/A+_(programming_language), drawing from the analogy of larger elements "bubbling up" through the array toward their final positions during each pass of the algorithm.[6] This name quickly gained traction due to its intuitive visualization, but it has faced criticism for being potentially misleading, as the process does not consistently prioritize the largest elements bubbling first in all implementations or passes, leading some to argue it oversimplifies the exchange mechanism.[34] Alternative terminologies have persisted, reflecting different emphases on the algorithm's behavior. Prior to Iverson's coinage, the method was commonly described as "sorting by exchange," a broader category highlighting the adjacent swaps central to the process, as noted in Edward H. Friend's 1956 paper on electronic computer sorting.[6] It has also been called "sinking sort," focusing instead on how smaller elements gradually "sink" to the bottom of the array, an alternative perspective emphasized in some early analyses to contrast with the upward movement of larger values.[35] Debates over terminology emerged prominently in the 1960s and continued into the 1980s through ACM publications and discussions, where figures like Donald Knuth critiqued the name while acknowledging its appeal. In The Art of Computer Programming, Volume 3 (1998 edition), Knuth described bubble sort as having "nothing to recommend it, except a catchy name," and positioned it within exchange sorts, suggesting terms like "insertion by exchange" to better align it with related algorithms such as insertion sort variants that rely on adjacent transpositions.[6] These conversations, including at the 1962 ACM Conference on Sorting, highlighted preferences for more precise descriptors like "exchange sort" to avoid confusion with other bubbling or insertion methods.[34] Despite these critiques, "bubble sort" became standardized in computer science education and literature by the late 20th century, appearing ubiquitously in textbooks alongside more efficient algorithms, even as warnings about its inefficiency persisted.[6] This endurance underscores the name's memorability, solidifying its place in pedagogical contexts over alternatives.

Applications

Practical Deployments

Bubble sort is employed in practical deployments where computational resources are severely limited and the dataset size is small, typically under 50 elements, as its straightforward implementation and constant space complexity make it preferable to more complex algorithms.[5][36] In such cases, the algorithm's O(n²) time complexity does not impose significant overhead, allowing simplicity to outweigh performance concerns.[5] In embedded systems, bubble sort sees occasional use due to its minimal memory footprint and ease of integration into resource-constrained environments, such as microcontrollers with limited RAM.[36] For instance, in reconfigurable embedded Java applications, bubble sort has been optimized as a kernel for tasks like sorting small arrays, achieving up to 47% energy savings through hardware reconfiguration while maintaining the algorithm's core logic.[37] This makes it suitable for IoT devices handling brief, low-volume data streams, such as prioritizing sensor readings or logging events from a handful of inputs.[36] Legacy code in older software systems or quick scripts often retains bubble sort implementations for ad-hoc sorting needs, where refactoring to advanced algorithms was not prioritized due to the infrequency of execution on small inputs.[5] Despite these niches, bubble sort is rarely deployed in modern production environments, as superior alternatives like quicksort or mergesort handle larger scales more effectively, relegating it primarily to prototypes and initial software sketches where rapid development trumps optimization.[36] It is unsuitable for large-scale applications, such as database indexing, where its quadratic scaling leads to prohibitive delays.[5]

Educational Role

Bubble sort serves as an ideal introductory algorithm for beginners in computer science due to its straightforward implementation, which clearly visualizes the process of pairwise comparisons and swaps, thereby reinforcing fundamental concepts such as nested loops and conditional statements.[5] Its simplicity allows novices to grasp the mechanics of sorting without overwhelming complexity, making it a staple in early programming education.[5] In introductory computer science courses, bubble sort is commonly employed to illustrate basic sorting principles and to provide a baseline for comparison with more efficient algorithms. For instance, Harvard's CS50 course features a dedicated module on bubble sort to demonstrate its operation within broader discussions of algorithmic design.[38] Similarly, MIT's 6.0001 Introduction to Computer Science and Programming in Python includes bubble sort in its lecture on searching and sorting, using it to teach iterative processes alongside selection and merge sorts.[39] By highlighting bubble sort's quadratic time complexity through simple examples, such as sorting a small array like [5, 3, 8, 4, 2] via repeated passes, educators motivate students to explore advanced techniques like quicksort and merge sort, underscoring the importance of algorithmic efficiency.[5] Educational resources further enhance bubble sort's pedagogical value through interactive tools and textual explanations. Textbooks such as Introduction to Algorithms by Cormen et al. include exercises on bubble sort to analyze its correctness and limitations, aiding in-depth understanding.[40] Online simulators, like those on Visualgo, offer step-by-step animations that depict the "bubbling" of elements, enabling visual learners to observe comparisons and swaps in real-time.[41] These aids collectively foster conceptual mastery of sorting fundamentals before advancing to optimized methods.

References

User Avatar
No comments yet.