Sweep through your data swapping adjacent items if they're the wrong way around. A factor of 2 improvement can be made by having successive sweeps get shorter. Time-complexity is (n-1)*(n-2)/2 comparisons and we expect (on average) to make half that many exchanges. If you don't swap equal items, it's stable.
Comes in two basic flavors. One scans the data until it knows there can be no problems remaining (n-1 sweeps, as above), the other sets a flag if items were swapped and sweeps until the flag remains false. The latter stops early if the data were almost sorted to start with but carries a small extra cost associated with having and setting the flag.
BubbleSort is easy to understand, easy to code, but inefficient. One hypothetical Really Aggressive Optimizer automatically recognizes undergraduate implementations of bubble sort and replaces them with something better.
Separating the ideas of "finding the largest" and "moving the largest" gives InsertionSort and SelectionSort, the comparative speeds of which depend on which is more expensive, comparisons or swaps. See those pages for more details.
BubbleSort is never faster than InsertionSort, so long as the InsertionSort does not use a binary search.
Sample code in CeeLanguage
void bubble_sort (int a[], int n /* the size of array */) { int i; for (i = 0; i < n - 1; i++) { int j; for (j = n - 1; j > i; j--) { if (a[j - 1] > a[j]) { /* Swap a adjacent pair of items. */ int t = a[j - 1]; a[j - 1] = a[j]; a[j] = t; } } } }This formulation obtains the advertised best-case performance of O(n). Otherwise, best-case == worse-case == average-case == O(n^2).
void bubble_sort (int a[], int n /* the portion of the array that is unsorted */) { int i, sorted; do { sorted = 1; --n; for (i = 0; i < n; i++) { if (a[i] > a[i + 1]) { /* Swap adjacent pair of items. */ int t = a[i]; a[i] = a[i + 1]; a[i + 1] = t; sorted = 0; } } } while (!sorted); }Sample code in PythonLanguage:
def bubble(alist): length = len(alist) for i in xrange(length-1): for j in xrange(length-i-1): if alist[j] > alist[j+1]: alist[j], alist[j+1] = alist[j+1], alist[j] def bubble_flag(alist): length = len(alist) for i in xrange(length-1): swapped = False for j in xrange(length-i-1): if alist[j] > alist[j+1]: alist[j], alist[j+1] = alist[j+1], alist[j] swapped = True if not swapped: return
sort: aCollection ^aCollection size < self switchSize ifTrue: [^self insertionSort: aCollection] ifFalse: [^self quickSort: aCollection]I tested a quick-coded bubble sort vs Dolphin's sort [DolphinSmalltalk?] (which I suppose is QuickSort, as most STs are, though I didn't look.) At 10 or 20 elements, the bubble was faster. At 100, the built-in sort was about 3x faster. -- RonJeffries
Care to find the break-even point, and then repeat, comparing the bubble sort with HeapSort?
I've always thought that Bubble Sort should be called Rock Sort because the in order elements actually fall to the bottom not bubble to the top. Depends purely on whether you run forwards or backwards.
8 7 7 3 7 8 3 5 9 3 5 7 3 5 8 8 5 9 9 9-- CurtisCooley
See also: BubbleSortChallenge