Sort an array of elements using the bubble sort algorithm. The elements must have a total order and the index of the array can be of any discrete type. For languages where this is not possible, sort an array of integers.

The bubble sort is generally considered to be the simplest sorting algorithm.

Because of its simplicity and ease of visualization, it is often taught in introductory computer science courses.

Because of its abysmal O(n2) performance, it is not used often for large (or even medium-sized) datasets.

The bubble sort works by passing sequentially over a list, comparing each value to the one immediately after it. If the first value is greater than the second, their positions are switched. Over a number of passes, at most equal to the number of elements in the list, all of the values drift into their correct positions (large values "bubble" rapidly toward the end, pushing others down around them).
Because each pass finds the maximum item and puts it at the end, the portion of the list to be sorted can be reduced at each pass.
A boolean variable is used to track whether any changes have been made in the current pass; when a pass completes without changing anything, the algorithm exits.

This can be expressed in pseudo-code as follows (assuming 1-based indexing):

GNU awk contains built in functions for sorting, but POSIX
Awk doesn't. Here is a generic bubble sort() implementation that you
can copy/paste to your
Awk programs. Adapted from the above example. Note that it
is not possible to return arrays from Awk functions so the
array is "edited in place". The extra parameters passed in
function's argument list is a well known trick to define local
variables.

# Test this example file from command line with:## awk -f file.awk /dev/null## Code by Jari Aalto <jari.aalto A T cante net># Licensed and released under GPL-2+, see http://spdx.org/licenses

The Bubble sort is very inefficient for 99% of cases. This routine uses a couple of 'tricks' to try and mitigate the inefficiency to a limited extent. Note that the array index is assumed to start at zero.

Bubble sorts a Java ArrayList in place. Uses 'doseq' iteration construct with a short-circuit when a pass didn't produce any change, and within the pass, an atomic 'changed' variable that gets reset whenever a change occurs.

elt has linear access time for lists, making the prior implementation of bubble-sort very expensive (although very clear, and straightforward to code. Here is an implementation that works efficiently for both vectors and lists. For lists it also has the nice property that the input list and the sorted list begin with the same cons cell.

This solution is presented in two classes. The first is a simple application that creates a set, an instance of MY_SORTED_SET, and adds elements to the set in unsorted order. It iterates across the set printing the elements, then it sorts the set, and reprints the elements.

This class inherits from the Eiffel library class TWO_WAY_SORTED_SET, which implements sets whose elements are comparable. Therefore, the set can be ordered and in fact is kept so under normal circumstances.

MY_SORTED_SET redefines only the routine sort which contains the implementation of the sort algorithm. The implementation in the redefined version of sort in MY_SORTED_SET uses a bubble sort.

Output:

Before: 7 10 4 8 9 3 5 1 6 2
After : 1 2 3 4 5 6 7 8 9 10

TWO_WAY_SORTED_SET is implemented internally as a list.
For this example, we use the feature put_front which explicitly adds each new element to the beginning of the list, allowing us to show that the elements are unordered until we sort them.
It also causes, in the "Before" output, the elements to be printed in the reverse of the order in which they were added.
Under normal circumstances, we would use the feature extend (rather than put_front) to add elements to the list.
This would assure that the order was maintained even as elements were added.

! init random number generator RANDOMIZE(TIMER)! fills array A% with random data FOR N=1 TO UBOUND(A%,1) DO A%[N]=RND(1)*256 END FOR! sort array FLIPS%=TRUE WHILE FLIPS% DO FLIPS%=FALSE FOR N=1 TO UBOUND(A%,1)-1 DO IF A%[N]>A%[N+1] THEN SWAP(A%[N],A%[N+1]) FLIPS%=TRUE END IF END FOR END WHILE! print sorted array FOR N=1 TO UBOUND(A%,1) DO PRINT(A%[N];) END FOR PRINTEND PROGRAM

This version is based on the above, but avoids sorting whole list each time. To implement this without a counter and retain using pattern matching, inner sorting is reversed, and then result is reversed back. Sorting is based on a predicate, e. g. (<) or (>).

Sorting illustrates a difference in the way Icon and Unicon handles data types. Built-in operators for comparing data types make a syntactic distinction between numeric and string types, and sorting structured and user-defined types require custom code. An added complication arises because mixed types are allowed. Two approaches are possible here: (1) that taken by the built-in sort which sorts first by type and then value The sort order of types is: &null, integer, real, string, cset, procedure, list, set, table, and record; and (2) Coercion of types which is used here (and implemented in 'sortop') to decide on using string or numeric sorting. These sorts will not handle more exotic type mixes.

The 'sortop' procedure allows various methods of comparison be selected including customized ones. The example could be made more general to deal with coercion of types like cset to string (admittedly an uninteresting example as csets are already sorted). Custom comparators are shown by and example procedure 'cmp'.

'demosort' can apply different sorting procedures and operators to lists and strings to show how this works. The routines 'displaysort' and 'writex' are helpers.

define(`set',`define(`$1[$2]',`$3')')define(`get',`defn(`$1[$2]')')define(`new',`set($1,size,0)')dnl for the heap calculations, it's easier if origin is 0, so set value firstdefine(`append', `set($1,size,incr(get($1,size)))`'set($1,get($1,size),$2)')

dnl swap(<name>,<j>,<name>[<j>],<k>) using arg stack for the temporarydefine(`swap',`set($1,$2,get($1,$4))`'set($1,$4,$3)')

A more "traditional" implementation of version 1 using only Rexx primitive constructs. This version has been tested with the Open Object Rexx and Regina Rexx interpreters and could equally have been exhibited as a Rexx solution.

function bubble_sort(sequence s)object tmpinteger changed for j=length(s) to 1 by -1 do changed = 0 for i=1 to j-1 do if s[i]>s[i+1] then {s[i],s[i+1],changed} = {s[i+1],s[i],1} end if end for if changed=0 then exit end if end for return send function

It's surprisingly easy in Prolog while coding this sort, to accidentally create a sort that is similar, but not identical
to the bubble sort algorithm. Some of these are easier and shorter to code and work as well if not better. Having said that,
it's difficult to think of a reason to code the bubble sort these days except as an example of inefficiency.

This solution is hosted at the Scratch site, because it is difficult to document visual programming solutions directly here at Rosetta Code. There you can see the solution results as well as examine the code. This solution is intended to illustrate the Bubble sort algorithm rather than to maximize performance. Scratch provides visual queues to indicate list access, and these are used to help show what is happening.

The next version has a postcondition to guarantee that the returned array is sorted correctly. This requires the two proof rules that follow the source. The Ada code is identical with the first version.

Both of the two versions above use an inner loop that scans over all the array on every pass of the outer loop. This makes the proof in the second version very simple.

The final version scans over a reducing portion of the array in the inner loop, consequently the proof becomes more complex. The package specification for this version is the same as the second version above. The package body defines two more proof functions.

Completion of the proof of this version requires more rules than the previous version and they are rather more complex. Creation of these rules is quite straightforward - I tend to write whatever rules the Simplifier needs first and then validate them afterwards. A formal proof of these rules from the definition of Sorted, In_Position and Swapped has been completed.